Apache SSL configuration, basic tests for Registry app via mod_epp

This commit is contained in:
Martin Lensment 2014-06-19 16:58:43 +03:00
parent 3d84d37219
commit 7d4142abc2
10 changed files with 172 additions and 64 deletions

10
Gemfile
View file

@ -49,12 +49,19 @@ group :development do
end end
group :development, :test do group :development, :test do
#EPP client
gem 'epp', '~> 1.4.0'
# Replacement for fixtures # Replacement for fixtures
gem 'fabrication', '~> 2.11.3' gem 'fabrication', '~> 2.11.3'
# Library to generate fake data # Library to generate fake data
gem 'faker', '~> 1.3.0' gem 'faker', '~> 1.3.0'
#For XML parsing
gem 'nokogiri', '~> 1.6.2.1'
# For debugging # For debugging
gem 'pry' gem 'pry'
gem 'pry-byebug' gem 'pry-byebug'
@ -64,4 +71,7 @@ group :development, :test do
# Additional matchers for RSpec # Additional matchers for RSpec
gem 'shoulda-matchers', '~> 2.6.1', require: false gem 'shoulda-matchers', '~> 2.6.1', require: false
# For unique IDs (used by the epp gem)
gem 'uuidtools', '~> 2.1.4'
end end

View file

@ -29,9 +29,9 @@ GEM
tzinfo (~> 1.1) tzinfo (~> 1.1)
arel (5.0.1.20140414130214) arel (5.0.1.20140414130214)
builder (3.2.2) builder (3.2.2)
byebug (1.1.1) byebug (2.7.0)
columnize (~> 0.3.6) columnize (~> 0.3)
debugger-linecache (~> 1.2.0) debugger-linecache (~> 1.2)
coderay (1.1.0) coderay (1.1.0)
coffee-rails (4.0.1) coffee-rails (4.0.1)
coffee-script (>= 2.2.0) coffee-script (>= 2.2.0)
@ -40,9 +40,12 @@ GEM
coffee-script-source coffee-script-source
execjs execjs
coffee-script-source (1.7.0) coffee-script-source (1.7.0)
columnize (0.3.6) columnize (0.8.9)
debugger-linecache (1.2.0) debugger-linecache (1.2.0)
diff-lcs (1.2.5) diff-lcs (1.2.5)
epp (1.4.0)
hpricot
libxml-ruby
erubis (2.7.0) erubis (2.7.0)
execjs (2.2.0) execjs (2.2.0)
fabrication (2.11.3) fabrication (2.11.3)
@ -56,8 +59,9 @@ GEM
haml (>= 3.1, < 5.0) haml (>= 3.1, < 5.0)
railties (>= 4.0.1) railties (>= 4.0.1)
hike (1.2.3) hike (1.2.3)
hpricot (0.8.6)
i18n (0.6.9) i18n (0.6.9)
jbuilder (2.1.0) jbuilder (2.1.1)
activesupport (>= 3.0.0, < 5) activesupport (>= 3.0.0, < 5)
multi_json (~> 1.2) multi_json (~> 1.2)
jquery-rails (3.1.0) jquery-rails (3.1.0)
@ -66,22 +70,26 @@ GEM
json (1.8.1) json (1.8.1)
kgio (2.9.2) kgio (2.9.2)
libv8 (3.16.14.3) libv8 (3.16.14.3)
libxml-ruby (2.7.0)
mail (2.5.4) mail (2.5.4)
mime-types (~> 1.16) mime-types (~> 1.16)
treetop (~> 1.4.8) treetop (~> 1.4.8)
method_source (0.8.2) method_source (0.8.2)
mime-types (1.25.1) mime-types (1.25.1)
minitest (5.3.4) mini_portile (0.6.0)
minitest (5.3.5)
multi_json (1.10.1) multi_json (1.10.1)
nokogiri (1.6.2.1)
mini_portile (= 0.6.0)
pg (0.17.1) pg (0.17.1)
polyglot (0.3.5) polyglot (0.3.5)
pry (0.10.0) pry (0.9.12.6)
coderay (~> 1.1.0) coderay (~> 1.0)
method_source (~> 0.8.1) method_source (~> 0.8)
slop (~> 3.4) slop (~> 3.4)
pry-byebug (1.0.1) pry-byebug (1.3.2)
byebug (~> 1.1.1) byebug (~> 2.7)
pry (>= 0.9.10) pry (~> 0.9.12)
rack (1.5.2) rack (1.5.2)
rack-test (0.6.2) rack-test (0.6.2)
rack (>= 1.0) rack (>= 1.0)
@ -156,24 +164,27 @@ GEM
coffee-rails coffee-rails
tzinfo (1.2.1) tzinfo (1.2.1)
thread_safe (~> 0.1) thread_safe (~> 0.1)
uglifier (2.5.0) uglifier (2.5.1)
execjs (>= 0.3.0) execjs (>= 0.3.0)
json (>= 1.8.0) json (>= 1.8.0)
unicorn (4.8.3) unicorn (4.8.3)
kgio (~> 2.6) kgio (~> 2.6)
rack rack
raindrops (~> 0.7) raindrops (~> 0.7)
uuidtools (2.1.4)
PLATFORMS PLATFORMS
ruby ruby
DEPENDENCIES DEPENDENCIES
coffee-rails (~> 4.0.0) coffee-rails (~> 4.0.0)
epp (~> 1.4.0)
fabrication (~> 2.11.3) fabrication (~> 2.11.3)
faker (~> 1.3.0) faker (~> 1.3.0)
haml-rails (~> 0.5.3) haml-rails (~> 0.5.3)
jbuilder (~> 2.0) jbuilder (~> 2.0)
jquery-rails jquery-rails
nokogiri (~> 1.6.2.1)
pg pg
pry pry
pry-byebug pry-byebug
@ -187,3 +198,4 @@ DEPENDENCIES
turbolinks turbolinks
uglifier (>= 1.3.0) uglifier (>= 1.3.0)
unicorn unicorn
uuidtools (~> 2.1.4)

View file

@ -48,15 +48,71 @@ index d8c463e..7f6e320 100644
* `sudo apxs2 -a -c -i mod_epp.c` * `sudo apxs2 -a -c -i mod_epp.c`
* `sudo a2enmod cgi` * `sudo a2enmod cgi`
* `sudo a2enmod authn_file` * `sudo a2enmod authn_file` (Will be used for non implicit authentication URIs, can be removed in the future)
* `sudo a2enmod proxy_http` * `sudo a2enmod proxy_http`
* `sudo htpasswd -c /etc/apache2/htpasswd test` * `sudo htpasswd -c /etc/apache2/htpasswd test` (can be removed in the future)
* Type "test" when prompted * Type "test" when prompted
* `cd /usr/lib/cgi-bin` * `cd /usr/lib/cgi-bin`
* `mkdir epp` * `mkdir epp`
* Copy the files from $mod_epp/examples/cgis to /usr/lib/cgi-bin/epp (this is just for now) * Copy the files from $mod_epp/examples/cgis to /usr/lib/cgi-bin/epp (once in production, majority of these scripts will not be needed (maybe only double the error script for failover))
* `cd /etc/apache2/sites-available` * sudo mkdir /etc/apache2/ssl
* `nano epp.conf` * sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/apache2/ssl/apache.key -out /etc/apache2/ssl/apache.crt
* `sudo nano /etc/apache2/sites-available/epp_ssl.conf`
For development configuration, add:
```apache
<IfModule mod_epp.c>
<Directory "/usr/lib/cgi-bin/epp">
Options ExecCGI
SetHandler cgi-script
</Directory>
Listen 700
<VirtualHost *:700>
SSLEngine on
SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL
SSLCertificateFile /etc/apache2/ssl/apache.crt
SSLCertificateKeyFile /etc/apache2/ssl/apache.key
SSLVerifyClient optional_no_ca
EPPEngine On
EPPCommandRoot /proxy/command
EPPSessionRoot /proxy/session
ProxyPass /proxy/ http://localhost:8080/epp/
EPPErrorRoot /cgi-bin/epp/error
EPPAuthURI implicit
EPPReturncodeHeader X-EPP-Returncode
</VirtualHost>
</IfModule>
```
For plain TCP EPP configuration, see below (may be useful for debugging purposes).
* `sudo a2ensite epp_ssl`
* `sudo service apache2 restart`
Try it out:
* Fire up your appserver (This setup is tested with Unicorn)
* `cd $mod_epp`
* `./epptelnet.pl localhost 1701`
You should receive the greeting from the registry server.
Wait for the greeting message on the STD, then send EPP/TCP frame:
```xml
<epp><command>
<login>
<clID>test</clID>
<pw>test</pw>
</login>
<clTRID>sample1trid</clTRID>
</command></epp>
```
Configuration on plain TCP EPP is as follows:
Add: Add:
```apache ```apache
@ -81,29 +137,7 @@ Add:
</IfModule> </IfModule>
``` ```
* `sudo a2ensite epp` For debugging purposes, standalone CGI scripts can be used:
* `sudo service apache2 restart`
Try it out:
* Fire up your appserver (I tested this setup with Unicorn)
* `cd $mod_epp`
* `./epptelnet.pl localhost 1701`
You should receive the greeting from the registry server.
Wait for a complete paragraph of text on STDIN before sending EPP/TCP frame.
```xml
<epp><command>
<login>
<clID>test</clID>
<pw>test</pw>
</login>
<clTRID>sample1trid</clTRID>
</command></epp>
```
Alternative virtual host config is as follows:
This needs a static greeting file, so you will have to make /var/www writable. This needs a static greeting file, so you will have to make /var/www writable.
```apache ```apache
@ -120,11 +154,9 @@ This needs a static greeting file, so you will have to make /var/www writable.
EPPCommandRoot /cgi-bin/epp/command EPPCommandRoot /cgi-bin/epp/command
EPPSessionRoot /cgi-bin/epp/session EPPSessionRoot /cgi-bin/epp/session
EPPErrorRoot /cgi-bin/epp/error EPPErrorRoot /cgi-bin/epp/error
# we can redirect to static pages.
Alias /cgi-bin/epp/session/hello /var/www/html/epp/session-hello Alias /cgi-bin/epp/session/hello /var/www/html/epp/session-hello
# or to specialized scripts
Alias /cgi-bin/epp/session/login /usr/lib/cgi-bin/epp/session-login Alias /cgi-bin/epp/session/login /usr/lib/cgi-bin/epp/session-login
Alias /cgi-bin/epp/session/logout /usr/lib/cgi-bin/epp/session-logout Alias /cgi-bin/epp/session/logout /usr/lib/cgi-bin/epp/session-logout
Alias /cgi-bin/epp/error/schema /usr/lib/cgi-bin/epp/error-schema Alias /cgi-bin/epp/error/schema /usr/lib/cgi-bin/epp/error-schema

View file

@ -1,13 +1,15 @@
class Epp::SessionsController < ApplicationController class Epp::SessionsController < ApplicationController
protect_from_forgery with: :null_session protect_from_forgery with: :null_session
def greeting; end
def proxy def proxy
send(params[:command]) send(params[:command])
end end
private private
def hello
render 'greeting'
end
def login def login
render 'login' render 'login'
end end

View file

@ -1,14 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:ietf:params:xml:ns:epp-1.0
epp-1.0.xsd">
<response>
<result code="1000">
<msg lang="en">User test was authenticated. Welcome.</msg>
</result>
<trID>
<clTRID>sample1trid</clTRID>
</trID>
</response>
</epp>

View file

@ -0,0 +1,12 @@
xml.instruct!
xml.epp('xmlns' => 'urn:ietf:params:xml:ns:epp-1.0', 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance', 'xsi:schemaLocation' => 'urn:ietf:params:xml:ns:epp-1.0 epp-1.0.xsd') do
xml.response do
xml.result('code' => '1000') do
xml.msg('User test was authenticated. Welcome.', 'lang' => 'en')
end
end
xml.trID do
xml.clTRID 'sample1trid'
end
end

View file

@ -1,7 +1,6 @@
Rails.application.routes.draw do Rails.application.routes.draw do
namespace(:epp) do namespace(:epp) do
get 'session/hello', to: 'sessions#greeting', defaults: { format: :xml } match 'session/:command', to: 'sessions#proxy', defaults: { format: :xml }, via: [:get, :post]
post 'session/:command', to: 'sessions#proxy', defaults: { format: :xml }
end end
# The priority is based upon order of creation: first created -> highest priority. # The priority is based upon order of creation: first created -> highest priority.

View file

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:ietf:params:xml:ns:epp-1.0 epp-1.0.xsd">
<command>
<login>
<clID>test</clID>
<pw>test</pw>
<options>
<version>1.0</version>
<lang>en</lang>
</options>
<svcs>
<objURI>http://www.nic.cz/xml/epp/contact-1.6</objURI>
<objURI>http://www.nic.cz/xml/epp/nsset-1.2</objURI>
<objURI>http://www.nic.cz/xml/epp/domain-1.4</objURI>
<objURI>http://www.nic.cz/xml/epp/keyset-1.3</objURI>
<svcExtension>
<extURI>http://www.nic.cz/xml/epp/enumval-1.2</extURI>
</svcExtension>
</svcs>
</login>
<clTRID>wgyn001#10-02-08at13:58:06</clTRID>
</command>
</epp>

View file

@ -1,5 +1,28 @@
require 'rails_helper' require 'rails_helper'
describe "EPP Session" do describe 'EPP Session', type: :epp do
it "greets client upon connection" let(:server) { server = Epp::Server.new({server: 'localhost', tag: 'test', password: 'test'}) }
context 'when not connected' do
it 'greets client upon connection' do
response = Nokogiri::XML(server.open_connection)
expect(response.css('epp svID').text).to eq('EPP server (DSDng)')
server.close_connection
end
end
context 'when connected' do
before(:each) { server.open_connection }
after(:each) { server.close_connection }
it 'logs in epp user' do
response = Nokogiri::XML(server.send_request(read_body('login.xml')))
result = response.css('epp response result').first
expect(result[:code]).to eq('1000')
msg = response.css('epp response result msg').text
expect(msg).to eq('User test was authenticated. Welcome.')
end
end
end end

9
spec/support/epp.rb Normal file
View file

@ -0,0 +1,9 @@
module Epp
def read_body(filename)
File.read("spec/epp/requests/#{filename}")
end
end
RSpec.configure do |c|
c.include Epp, type: :epp
end