We will work through the setting up of a new domain. To do this, we first have to introduce the domain name as a known name in cyberspace. This is done with the Domain Name Systems, a.k.a. DNS. The result is that the website address, di.metri.us in this case, will be know as a certain IP address. When this is done, a name exists and nothing more. Use of this address at this time will result in a the browser looking for a server which might not exist, and if it exists, might be unprepared to resond to the browser's request.
The next step, then, is to clear the network path to the machine with the given IP address. The global routing structure of the Internet will take the request to my door, but we have a firewall which prevents the request to proceed further than the door. The firewall uses Network Address Translation, a.k.a. NAT, to regulate requests coming into my local network. Each machine on my local network uses local IP addresses which are not visible to the Internet. For the request to get to my server the firewall must rewrite the global IP address specified by the request packet to the local IP address of my machine, and the firewall must specifically permit passage of the packet according to certain security rules.
Now the browser requests is getting into the local network and has a the local address for a destination. SSL requires that each web site have its own IP address. Only in this way can the SSL handshake provide the correct certificate to the browser. A single machine can have multiple IP addresses, and we have to configure the web server to now recognize the new IP adress. The web server softare, Apache, must also be configured to handle the requests on that configured address. A single running instance of Apache can handle multiple IP addresses, and can correctly send off the connection to the correct set of web pages.
To create the di.metri.us domain we need to create an A record for that domain containing the IP address of the server for di.metri.us. The domain metri.us is owned by me and I use GoDaddy as the DNS server for this name. So I log onto my GoDaddy account and add the subdomain di and include the appropriate A record.
[burt@sherman Csc598.073]$ dig psi.metri.us ; <<>> DiG 8.3 <<>> psi.metri.us ;; res options: init recurs defnam dnsrch ;; got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 2 ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 2, ADDITIONAL: 2 ;; QUERY SECTION: ;; psi.metri.us, type = A, class = IN ;; ANSWER SECTION: psi.metri.us. 1H IN A 192.31.89.7 ;; AUTHORITY SECTION: metri.us. 1h42m54s IN NS PARK32.SECURESERVER.NET. metri.us. 1h42m54s IN NS PARK31.SECURESERVER.NET. ;; ADDITIONAL SECTION: PARK32.SECURESERVER.NET. 15h48m16s IN A 208.109.80.74 PARK31.SECURESERVER.NET. 15h48m16s IN A 64.202.165.123 ;; Total query time: 70 msec ;; FROM: sherman.cs.miami.edu to SERVER: default -- 127.0.0.1 ;; WHEN: Wed Jun 6 12:48:55 2007 ;; MSG SIZE sent: 30 rcvd: 148 [burt@sherman Csc598.073]$ nslookup Default Server: localhost.cs.miami.edu Address: 127.0.0.1 > server park32.secureserver.net Default Server: park32.secureserver.net Address: 208.109.80.74 > psi.metri.us Server: park32.secureserver.net Address: 208.109.80.74 Name: psi.metri.us Address: 192.31.89.7 > di.metri.us Server: park32.secureserver.net Address: 208.109.80.74 Name: di.metri.us Address: 192.31.89.11 [burt@sherman Csc598.073]$ dig @park32.secureserver.net di.metri.us ; <<>> DiG 8.3 <<>> @park32.secureserver.net di.metri.us ; (1 server found) ;; res options: init recurs defnam dnsrch ;; got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 4 ;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 2, ADDITIONAL: 0 ;; QUERY SECTION: ;; di.metri.us, type = A, class = IN ;; ANSWER SECTION: di.metri.us. 30M IN A 192.31.89.11 ;; AUTHORITY SECTION: metri.us. 1H IN NS park31.secureserver.net. metri.us. 1H IN NS park32.secureserver.net. ;; Total query time: 65 msec ;; FROM: sherman.cs.miami.edu to SERVER: park32.secureserver.net 208.109.80.74 ;; WHEN: Wed Jun 6 13:05:40 2007 ;; MSG SIZE sent: 29 rcvd: 103
Since we are working from behind a firewall, locally di.metri.us will have a different, local address. We first install that A record in or local name server. Here is how:
sherman# nsupdate > update add grant-B.cs.miami.edu 3600 A 172.21.0.11 > [burt@sherman Csc598.073]$ dig grant-B.cs.miami.edu ; <<>> DiG 8.3 <<>> grant-B.cs.miami.edu ;; res options: init recurs defnam dnsrch ;; got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 2 ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 1 ;; QUERY SECTION: ;; grant-B.cs.miami.edu, type = A, class = IN ;; ANSWER SECTION: grant-B.cs.miami.edu. 1H IN A 172.21.0.11 ;; AUTHORITY SECTION: cs.miami.edu. 1D IN NS sherman.cs.miami.edu. ;; ADDITIONAL SECTION: sherman.cs.miami.edu. 1D IN A 172.20.0.2 ;; Total query time: 0 msec ;; FROM: sherman.cs.miami.edu to SERVER: default -- 127.0.0.1 ;; WHEN: Wed Jun 6 12:42:29 2007 ;; MSG SIZE sent: 38 rcvd: 92
The firewall is a Cisco PIX. We have to map the outside IP adress to the inside address by making a static entry between the two security levels: outside and sandbox (our target webserver is in the sandbox security level). The second step is to allow http and https data to flow through this static, by modifying the outward facing access list.
cs-gate(config)# static (sandbox,outside) 192.31.89.11 172.21.0.11 netmask 255.255.255.255 0 0 cs-gate(config)# show static static (public,outside) 192.31.89.3 172.18.0.2 netmask 255.255.255.255 0 0 static (sandbox,outside) 192.31.89.7 172.21.0.7 netmask 255.255.255.255 0 0 static (sandbox,outside) 192.31.89.11 172.21.0.11 netmask 255$ cs-gate(config)# access-list acl_out permit tcp any host 192.31.89.11 eq www cs-gate(config)# access-list acl_out permit tcp any host 192.31.89.11 eq https cs-gate(config)# show access-list access-list acl_out; 15 elements access-list acl_out permit icmp any any (hitcnt=1235348) access-list acl_out permit tcp any host 192.31.89.2 eq ssh (hitcnt=281501) access-list acl_out permit tcp any host 192.31.89.3 eq www (hitcnt=4889353) access-list acl_out permit tcp any host 192.31.89.3 eq domain (hitcnt=230909) access-list acl_out permit udp any host 192.31.89.3 eq domain (hitcnt=6136272) access-list acl_out permit tcp any host 192.31.89.5 eq ssh (hitcnt=166444) access-list acl_out permit tcp any host 192.31.89.5 eq smtp (hitcnt=181126) access-list acl_out permit tcp any host 192.31.89.2 eq smtp (hitcnt=82548) access-list acl_out permit tcp any host 192.31.89.7 eq www (hitcnt=228970) access-list acl_out permit tcp any host 192.31.89.6 eq ssh (hitcnt=198243) access-list acl_out permit tcp any host 192.31.89.6 eq smtp (hitcnt=144) access-list acl_out permit tcp any host 192.31.89.9 eq smtp (hitcnt=49264) access-list acl_out permit tcp any host 192.31.89.7 eq https (hitcnt=39) access-list acl_out permit tcp any host 192.31.89.11 eq www (hitcnt=0) access-list acl_out permit tcp any host 192.31.89.11 eq https (hitcnt=0) access-list acl_pub; 22 elements cs-gate(config)# exit cs-gate# write mem Building configuration... Cryptochecksum: 462369d9 0717b743 19bf28ba 75c3462d [OK]
Now to test the firewall configuration by trying to contact the server using a raw telnet and checking that the hit count for the access-list rule increments.
[burt@sherman Csc598.073]$ telnet 192.31.89.11 80 Trying 192.31.89.11... cs-gate# show access-list access-list acl_out; 15 elements access-list acl_out permit icmp any any (hitcnt=1235350) access-list acl_out permit tcp any host 192.31.89.2 eq ssh (hitcnt=281501) access-list acl_out permit tcp any host 192.31.89.3 eq www (hitcnt=4889385) access-list acl_out permit tcp any host 192.31.89.3 eq domain (hitcnt=230909) access-list acl_out permit udp any host 192.31.89.3 eq domain (hitcnt=6136294) access-list acl_out permit tcp any host 192.31.89.5 eq ssh (hitcnt=166444) access-list acl_out permit tcp any host 192.31.89.5 eq smtp (hitcnt=181126) access-list acl_out permit tcp any host 192.31.89.2 eq smtp (hitcnt=82549) access-list acl_out permit tcp any host 192.31.89.7 eq www (hitcnt=228971) access-list acl_out permit tcp any host 192.31.89.6 eq ssh (hitcnt=198243) access-list acl_out permit tcp any host 192.31.89.6 eq smtp (hitcnt=144) access-list acl_out permit tcp any host 192.31.89.9 eq smtp (hitcnt=49264) access-list acl_out permit tcp any host 192.31.89.7 eq https (hitcnt=39) access-list acl_out permit tcp any host 192.31.89.11 eq www (hitcnt=1) access-list acl_out permit tcp any host 192.31.89.11 eq https (hitcnt=0) access-list acl_pub; 22 elements
We add the new IP address to the network interface of the webserver. This is going to be specific to the version of Unix you are using. We are using FreeBSD. The following is added to /etc/rc.conf:
defaultrouter="172.21.0.1" hostname="grant.cs.miami.edu" ifconfig_fxp0="inet 172.21.0.7 netmask 255.255.0.0" ifconfig_fxp0_alias0="inet 172.21.0.11 netmask 255.255.0.0"
And we restart networking using /etc/rc.d/netif restart. We check the configuration:
burt@grant$ ifconfig fxp0: flags=8843mtu 1500 options=8 inet6 fe80::2d0:b7ff:fee8:c3b5%fxp0 prefixlen 64 scopeid 0x1 inet 172.21.0.7 netmask 0xffff0000 broadcast 172.21.255.255 inet 172.21.0.11 netmask 0xffff0000 broadcast 172.21.255.255 ether 00:d0:b7:e8:c3:b5 media: Ethernet autoselect (100baseTX ) status: active burt@grant$ telnet 172.21.0.11 80 Trying 172.21.0.11... Connected to 172.21.0.11. Escape character is '^]'. GET / HTTP/1.1 Host: web.cs.miami.edu HTTP/1.1 200 OK Date: Wed, 06 Jun 2007 17:13:25 GMT Server: Apache/2.2.0 (FreeBSD) mod_ssl/2.2.0 OpenSSL/0.9.7e DAV/2 PHP/5.1.4 Last-Modified: Tue, 01 Aug 2006 05:14:59 GMT ETag: "10b084b-313-dc313ac0" Accept-Ranges: bytes Content-Length: 787 Content-Type: text/html ... [ page content here ] ...
At this point we have a webserver at the IP address of di.metri.us, and the firewall will allow connections. Now we configure Apache. We have to tell Apache which data directory to use for connections at the di.metri.us address. Before this configuration step, Apache will return the main pages. There are two types of virtual hosting that can be configured: Name and IP address. We are using both on our server. Name-based means that the same IP address is used for multiple sites. The browser will always specify to the server, as part of the request, which site it is interested in. This method cannot be used for SSL, since certificate delivery does not depend on http or the browser, it depends on the IP address. So multiple certificates require multiple IP addresses. Here is the configuration:
NameVirtualHost 172.21.0.7:80 <VirtualHost 172.21.0.11:80> ServerName di.metri.us ServerAdmin burt@cs.miami.edu DocumentRoot "/home/burt/public_html/dimetrius" </VirtualHost> <VirtualHost 172.21.0.7:80> ServerName web.cs.miami.edu ServerAdmin burt@cs.miami.edu DocumentRoot "/usr/local/www/apache22/data" </VirtualHost> <VirtualHost 172.21.0.7:80> ServerName wiki.cs.miami.edu ServerAdmin burt@cs.miami.edu DocumentRoot "/usr/local/www/apache22/data" # ServerAlias x y z ErrorLog /var/log/httpd-wiki-error.log CustomLog /var/log/httpd-wiki-common.log common RedirectMatch ^/$ /pages/ Alias /pages/ "/usr/local/www/data/dokuwiki/" </VirtualHost> <VirtualHost 172.21.0.7:80> ServerName psy.metri.us ServerAdmin burt@cs.miami.edu DocumentRoot "/home/burt/public_html/pmk/htdocs" </VirtualHost>
We check it, and it works.