В этом примере два участка объеденены между собой через OpenVPN тунель в режиме SSL/TLS с некоторыми опциональными полезными настройками.
Основные цели примера:
- установить подключение между двумя локальными сетями (10.0.1.0/24 и 10.0.2.0/24) через OpenVPN на Linux VPN-узлах; тоесть две сети будут видеть друг-друга, как бы они были в одной сети, разделенной маршрутизаторами;
- разрешить пользователям локальных сетей использовать Internet (TCP port 80 (HTTP) и 443 (HTTPS)); необходим (NAT) на Linux VPN-узлах;
- защитить Linux VPN-узлы с Netfilter Linux Firewall kernel module
Первое, что нужно сделать, это настроить параметры IP на устройствах OpenVPN и настольных компьютерах локальной сети.
Для OpenVPN Server
Установки IP для интерфейсов:
#ifconfig eth0 50.0.0.1 netmask 255.255.255.0 #ifconfig eth1 10.0.1.1 netmask 255.255.255.0 |
Установка шлюза по умолчанию:
#route add default gateway 50.0.0.100 |
Если нужно сохранить настройки, нужно отредактировать /etc/network/interfaces файлы:
#vim /etc/network/interfaces |
auto lo iface lo inet loopback
auto eth0 iface eth0 inet static address 50.0.0.1 netmask 255.255.255.0 gateway 50.0.0.100
auto eth1 iface eth1 inet static address 10.0.1.1 netmask 255.255.255.0 |
Для OpenVPN Client
Установка IP
#ifconfig eth0 100.0.0.1 netmask 255.255.255.0 #ifconfig eth1 10.0.2.1 netmask 255.255.255.0 |
Установка шлюза по умолчанию::
#route add default gateway 100.0.0.100 |
Если нужно сохранить настройки, нужно отредактировать /etc/network/interfaces файлы:
#vim /etc/network/interfaces |
auto lo iface lo inet loopback
auto eth0 iface eth0 inet static address 100.0.0.1 netmask 255.255.255.0 gateway 100.0.0.100
auto eth1 iface eth1 inet static address 10.0.2.1 netmask 255.255.255.0 |
Для ПК Site A
IP address: Netmask: Gateway: | 10.0.1.100 255.255.255.0 10.0.1.1 |
Для ПК Site В
IP address: Netmask: Gateway: | 10.0.2.100 255.255.255.0 10.0.2.1 |
Файлы использованные OpenVPN будут в директории /etc/openvpn
OpenVPN будет использовать следующие файлы:
openvpn.conf - OpenVPN configuration file.
ipp.txt (server only) - a IP reservation file used for dynamic IP assignment.
route.txt (server only)- script to add a route on the server when the tunnel is up.
Файлы созданые certificate
authority (CA), см
SSL/PKI tutorial для информации как их создать.
ca.crt - the certificate authority certificate (CA public key).
server.crt or
client.crt - the server or client certificate (server or client public key).
server.key or
client.key - the server or client private key.
dh1024pem (server only) - the Diffie-Hellman (DH) settings.
Конфигурационный файл openvpn.conf
| SERVER | | CLIENT |
 | # Listening server IP address local 50.0.0.1 # Local port lport 2000 # Remote port rport 2001 # Tunnel mode dev tap # CA certificate ca ca.crt # Server certificate cert server.crt # Server private key key server.key # Diffie-Hellman dh dh1024.pem # DHCP range, server will take # 10.7.0.1 server 10.7.0.0 255.255.255.248 # IP reservation file ifconfig-pool-persist ipp.txt # Push a route to the client push "route 10.0.1.0 255.255.255.0" # Encryption ciper AES-256-CBC # Authentication auth MD5 # Compression is activated comp-lzo # Allowed clients max-clients 10 # Reduce the OpenVPN daemon's # privileges after initialization # (Linux only) user nobody # OpenVPN statistics status openvpn-status.log # Verbosity level verb 2 # Script launched when the tunnel is # up up "./route.txt" # After initialization, OpenVPN can # only access a directory # (Linux only) chroot /etc/openvpn/ | | # Server WAN IP address remote 50.0.0.1 # Local port lport 2001 # Remote port rport 2000 # Tunnel mode dev tap # CA certificate ca ca.crt # Client certificate cert client.crt # Client private key key client.key
# Encryption ciper AES-256-CBC # Authentication auth MD5 # Compression is activated comp-lzo
# Reduce the OpenVPN daemon's # privileges after initialization # (Linux only) user nobody # OpenVPN statistics status openvpn-status.log # Verbosity level verb 2
# After initialization, OpenVPN can only # access a directory # (Linux only) chroot /etc/openvpn/ # The client accepts options pushed # by the server pull |
Here is a summary of the OpenVPN functionnalities used in our tutorial compared to their default value.
Optional settings: Tunnel mode DHCP server Persistant addresses route push cipher auth compression Server source port Server destination port User rights Max-user "up" script IP assignment Verbosity level | Case study dev tap server 10.7.0.0 255.255.255.248 ifconfig-pool-persist ipp.txt push "10.0.1.0 255.255.255.0" cipher AES auth md5 comp-lzo lport 2000 rport 2001 user nodody chroot /etc/openvpn 10 up "route.txt" ifconfig-pool-persist file_name verb 2 | Default settings: dev tun - - - cipher BF-CBC auth sha1 - lport 1194 rport 1194 user root - - (Unlimited) - - verb 0 |
Be sure to add the ".conf" file extension to your configuration file. This is required to use the /etc/init.d/openvpn script to start OpenVPN automatically.
ipp.txt file:
The file /etc/openvpn/ipp.txt is used to store the IP reservations when the OpenVPN server dynamically assigns IP addresses to clients.
The syntax is the following:
certificate_client_name,ip_address
The certificate_client_name is the name chosen when creating the client certificate, see the OpenVPN PKI tutorial. In our case study, we chose client1 as the certificate_client_name.
route.txt file:
When the server is up, it will launch the "route.txt" bash script which will add a route on it to reach the client local network.
#!/bin/bash route add -net 10.0.2.0/24 gw 10.7.0.6 |
-------------------------------------
Last thing to do is to set the files permissions inside the /etc/openvpn directory.
The user teddy has read/write/execute permissions. None else has any permissions at all.
The most important file inside the directory are the private keys (server.key or client.key depending on which system you are using). If your server public key is captured, this will mean that all your Open VPN architecture is compromised!
#chmod 700 /etc/openvpn/* |
The user teddy is the owner of the files inside the /etc/openvpn directory.
#chown teddy /etc/openvpn/* |
Let's start OpenVPN on the client and the server and check the logs:
#openvpn /etc/openvpn/openvpn.conf |
Server log:
1
16
22 21 10 8/11
15
14
3 4
2
17 18
5 6
12 | OpenVPN 2.0.9 i486-pc-linux-gnu [SSL] [LZO] [EPOLL] built on Mar 2 2007 WARNING: No server certificate verification method has been enabled. See http://openvpn.net/howto.html#mitm for more info. LZO compression initialized Control Channel MTU parms [ L:1586 D:138 EF:38 EB:0 ET:0 EL:0 ] Data Channel MTU parms [ L:1586 D:1450 EF:54 EB:135 ET:32 EL:0 AF:3/1 ] Local Options hash (VER=V4): '579db898' Expected Remote Options hash (VER=V4): 'a0883d96' chroot to '/etc/openvpn' and cd to '/' succeeded UID set to nobody UDPv4 link local (bound): [undef]:2001 UDPv4 link remote: 50.0.0.1:2000 TLS: Initial packet from 50.0.0.1:2000, sid=100aa16d 662ac586 VERIFY OK: depth=1, /C=US/ST=CA/L=SanFrancisco/O=OpenManiak/ CN=OpenManiak_CA/emailAddress=opensource@openmaniak.com VERIFY OK: depth=0, /C=US/ST=CA/L=SanFrancisco/O=OpenManiak/ CN=server/emailAddress=opensource@openmaniak.com Data Channel Encrypt: Cipher 'AES-256-CBC' initialized with 256 bit key Data Channel Encrypt: Using 128 bit message hash 'MD5' for HMAC authentication Data Channel Decrypt: Cipher 'AES-256-CBC' initialized with 256 bit key Data Channel Decrypt: Using 128 bit message hash 'MD5' for HMAC authentication Control Channel: TLSv1, cipher TLSv1/SSLv3 DHE-RSA-AES256-SHA, 1024 bit RSA [server] Peer Connection Initiated with 50.0.0.1:2000 SENT CONTROL [server]: 'PUSH_REQUEST' (status=1) PUSH: Received control message: 'PUSH_REPLY,route 10.0.1.0 255.255.255.0, route-gateway 10.7.0.1,ifconfig 10.7.0.6 255.255.255.248' OPTIONS IMPORT: --ifconfig/up options modified OPTIONS IMPORT: route options modified TUN/TAP device tap0 opened ifconfig tap0 10.7.0.6 netmask 255.255.255.248 mtu 1500 broadcast 10.7.0.7 route add -net 10.0.1.0 netmask 255.255.255.0 gw 10.7.0.1 Initialization Sequence Completed |
Legend:
1. 2. 3. 4. | OpenVPN version Security mode Cipher algorithm Hash algorithm | 5. 6. 7. 8. | TUN/TAP drivers Tunnel MTU Tunnel Local IP Tunnel Remote IP | 9. 10. 11. 12. | OpenVPN server Local port Remote port OpenVPN status |
13. 14. 15. 16. | Client certificat Server certificat CA certificat compression | 17. 18. 19. | Route pushed to client IP pushed to client IP reservation | 21. 22. 23 | User ID Process limitation "up" script |
Client log:
1
5 6/7 23
22 21 9 10
19
12
8 16 11
15
13
3 4
2
17 18 | OpenVPN 2.0.9 i486-pc-linux-gnu [SSL] [LZO] [EPOLL] built on Mar 2 2007 WARNING: --keepalive option is missing from server config Diffie-Hellman initialized with 1024 bit key TLS-Auth MTU parms [ L:1586 D:138 EF:38 EB:0 ET:0 EL:0 ] TUN/TAP device tap0 opened ifconfig tap0 10.7.0.1 netmask 255.255.255.248 mtu 1500 broadcast 10.7.0.7 ./echo.txt tap0 1500 1586 10.7.0.1 255.255.255.248 init Data Channel MTU parms [ L:1586 D:1450 EF:54 EB:135 ET:32 EL:0 AF:3/1 ] chroot to '/etc/openvpn' and cd to '/' succeeded UID set to nobody UDPv4 link local (bound): 50.0.0.1:2000 UDPv4 link remote: [undef] MULTI: multi_init called, r=256 v=256 IFCONFIG POOL: base=10.7.0.2 size=5 IFCONFIG POOL LIST client1,10.7.0.6 Initialization Sequence Completed MULTI: multi_create_instance called 100.0.0.1:2001 Re-using SSL/TLS context 100.0.0.1:2001 LZO compression initialized 100.0.0.1:2001 Control Channel MTU parms [ L:1586 D:138 EF:38 EB:0 ET:0 EL:0 ] 100.0.0.1:2001 Data Channel MTU parms [ L:1586 D:1450 EF:54 EB:135 ET:32 EL:0 AF:3/1 ] 100.0.0.1:2001 Local Options hash (VER=V4): 'a0883d96' 100.0.0.1:2001 Expected Remote Options hash (VER=V4): '579db898' 100.0.0.1:2001 TLS: Initial packet from 100.0.0.1:2001, sid=85abe7b5 a5dcafc0 100.0.0.1:2001 VERIFY OK: depth=1, /C=US/ST=CA/L=SanFrancisco/O=OpenManiak/ CN=OpenManiak_CA/emailAddress=opensource@openmaniak.com 100.0.0.1:2001 VERIFY OK: depth=0, /C=US/ST=CA/L=SanFrancisco/O=OpenManiak/ CN=client1/emailAddress=opensource@openmaniak.com 100.0.0.1:2001 Data Channel Encrypt: Cipher 'AES-256-CBC' initialized with 256 bit key 100.0.0.1:2001 Data Channel Encrypt: Using 128 bit message hash 'MD5' for HMAC authentication 100.0.0.1:2001 Data Channel Decrypt: Cipher 'AES-256-CBC' initialized with 256 bit key 100.0.0.1:2001 Data Channel Decrypt: Using 128 bit message hash 'MD5' for HMAC authentication 100.0.0.1:2001 Control Channel: TLSv1, cipher TLSv1/SSLv3 DHE-RSA-AES256-SHA, 1024 bit RSA 100.0.0.1:2001 [client1] Peer Connection Initiated with 100.0.0.1:2001 client1/100.0.0.1:2001 PUSH: Received control message: 'PUSH_REQUEST' client1/100.0.0.1:2001 SENT CONTROL [client1]: 'PUSH_REPLY,route 10.0.1.0 255.255.255.0,route-gateway 10.7.0.1,ifconfig 10.7.0.6 255.255.255.248' (status=1) client1/100.0.0.1:2001 MULTI: Learn: 12:5a:a3:22:f7:11 -> client1/100.0.0.1:2001 |
The ping utility is very useful to test if the tunnel is up.
The server (10.7.0.1) should be able to ping the client (10.7.0.6) and vice versa.
An init.d script is available to start or stop OpenVPN. Be sure, as indicated in the Configurations section, that your configuration file are located in the /etc/openvpn directory and have a ".conf" extension file.
#/etc/init.d/openvpn stop |
Stopping virtual private network daemon: openvpn.
#/etc/init.d/openvpn start |
Starting virtual private network daemon: openvpn.
#/etc/init.d/openvpn restart |
Stopping virtual private network daemon: openvpn.
Starting virtual private network daemon: openvpn(OK).
The logs will be written by default in the /var/log/syslog file.
You can check the OpenVPN process status:
UID | PID | PPID | C | STIME | TTY | TIME | CMD |
nobody | 2792 | 1 | 0 | 09:59 | ? | 00:00:00 | /usr/sbin/openvpn -- writepid /var/run/openvpn.conf.pid --daemon ovpn-conf --cd /etc/openvpn --config /etc/openvpn/openvpn.conf |
Check the routing table on the OpenVPN server:
Kernel IP routing table |
Destination | Gateway | Genmask | Flags | Metric | Ref | Use | Iface |
10.7.0.0 | 0.0.0.0 | 255.255.255.248 | U | 0 | 0 | 0 | tap0 |
10.0.2.0 | 10.7.0.6 | 255.255.255.0 | UG | 0 | 0 | 0 | tap0 |
50.0.0.0 | 0.0.0.0 | 255.255.255.0 | U | 0 | 0 | 0 | eth0 |
0.0.0.0 | 50.0.0.100 | 0.0.0.0 | UG | 0 | 0 | 0 | eth0 |
Let's check which UDP or TCP ports are opened:
The goal is to close all the unnecessary opened ports to improve the security by preventing potential attacks.
Let's identify the TCP and UDP opened ports on our test Linux which is an Ubuntu 7.10 Desktop Edition.
UDP ports:
-u: UDP
-t: TCP
-a: all
-e: extended
-n: numeric
Active Internet connections (servers and established) |
Proto | Recv-Q | Send-Q | Local Address | Foreign Address | State | User | Inode |
udp | 0 | 0 | 0.0.0.0:1025 | 0.0.0.0:* | | 105 | 15129 |
udp | 0 | 0 | 50.0.0.1:2000 | 0.0.0.0:* | | 0 | 17810 |
udp | 0 | 0 | 0.0.0.0:5353 | 0.0.0.0:* | | 105 | 15128 |
Let's see which users own the ID "0" and "105".
user: | status: | userid: | groupid: | description: | home_directory: | shell |
root: | x: | 0: | 0: | root: | /root: | /bin/bash |
avahi: | x: | 105: | 105: | Avahi mDNS daemon,,,: | /var/run/avahi-daemon: | /bin/false |
Avahi is a daemon that allows programs to publish and discover services and hosts running on a local network with no specific configuration.
This daemon is not needed in our case study so we can either deactivate or uninstall it.
Note that the two avihi ports are already closed on the Ubuntu server edition.
Stop the daemon:
#/etc/init.d/avihi-daemon stop |
Deactivate the avahi at startup:
In the /etc/defaut/avahi-daemon file, set the AVAHI_DAEMON_START from "1" to "0":
Uninstall the daemon:
#apt-get remove avihi-daemon |
The unnecessary Avihi daemon is no longer running, so we can now check the UDP ports status again and see that the OpenVPN port is the only opened UDP port.
Active Internet connections (servers and established) |
Proto | Recv-Q | Send-Q | Local Address | Foreign Address | State | User | Inode |
udp | 0 | 0 | 50.0.0.1:2000 | 0.0.0.0:* | | 0 | 17810 |
TCP ports:
Active Internet connections (servers and established) |
Proto | Recv-Q | Send-Q | Local Address | Foreign Address | State | User | Inode |
tcp | 0 | 0 | 127.0.0.0.1:631 | 0.0.0.0:* | LISTEN | 0 | 15395 |
tcp | 0 | 0 | 127.0.0.0.1:2207 | 0.0.0.0:* | LISTEN | 108 | 15469 |
tcp | 0 | 0 | 127.0.0.0.1:2208 | 0.0.0.0:* | LISTEN | 0 | 15426 |
tcp6 | 0 | 0 | :::22 | :::* | LISTEN | 0 | 15688 |
TCP ports 631 (cupsys), 2207 and 2208 (hplip) are printer ports and not needed in our case study. So we can uninstall the associated services and thus close the ports.
Note that the three printer ports are already closed on the Ubuntu server edition.
#apt-get remove hplip #apt-get remove cupsys |
The unneeded printer daemons are no longer running, we can now check the TCP ports status again and see that the SSH port is the only opened TCP port.
Active Internet connections (servers and established) |
Proto | Recv-Q | Send-Q | Local Address | Foreign Address | State | User | Inode |
tcp6 | 0 | 0 | :::22 | :::* | LISTEN | 0 | 15688 |
IPtables is a tool needed to configure Netfilter and must be launched as root.
NetFilter is a Linux kernel module available since the kernel version 2.4. It provides three main functionalities:
- Packet filtering - Accepts or drops packets
- NAT - Changes the source or destination IP address of network packets
- Packet mangling - Modifies packets (as for Quality of Service, QoS)
The goal for us is to open only the needed ports and to close all the other to limit potential attacks on our Linux systems.
Our case study security strategy is the following:
Filter rules:
- Open the ports used by OpenVPN to generate the tunnel between the two Linux systems.
- Open the 80 and 443 ports to the outside to let the LAN machines surf on the Internet.
- Accept all traffic inside the tunnel.
- Drop all the rest.
OpenVPN Server Linux configuration:
- RESET YOUR IPTABLES SETTINGS:
--------------------------------------------------------
- DEFAULT POLICIES:
Set the rules to deny by default all the incoming and outgoing traffics and accept the forward traffic (inter-interface routing):
#iptables -P OUTPUT DROP #iptables -P INPUT DROP #iptables -P FORWARD ACCEPT |
--------------------------------------------------------
- OPENVPN RULES:
Authorize the OpenVPN tunnel:
#iptables -A INPUT -i eth0 -p udp -s 100.0.0.1 -d 50.0.0.1 --sport 2001 --dport 2000 -j ACCEPT #iptables -A OUTPUT -o eth0 -p udp -s 50.0.0.1 -d 100.0.0.1 --sport 2000 --dport 2001 -j ACCEPT |
Authorize all the traffic inside the tunnel:
#iptables -A INPUT -i tap+ -p all -j ACCEPT #iptables -A OUTPUT -o tap+ -p all -j ACCEPT |
--------------------------------------------------------
- LAN INTERFACE
All the traffic to and from the LAN interface (eth1) is accepted:
#iptables -A INPUT -i eth1 -p all -s 10.0.1.0/24 -j ACCEPT #iptables -A OUTPUT -o eth1 -p all -d 10.0.1.0/24 -j ACCEPT |
--------------------------------------------------------
- INTERNET ACCESS:
NAT rule:
Users from the site A network must be able to surf on the Internet, this will require NAT settings.
For example, when the Desktop located in Site A wants to access a web page on the Internet, its source IP address is translated and takes the OpenVPN server WAN IP address. In other words, 10.0.1.100 is translated to 50.0.0.1 and vice versa when the packets come back to the Desktop.
This kind of NAT is called 'masquerade'.
#iptables -t nat -A POSTROUTING -j MASQUERADE |
Internet access authorization:
LAN users are allowed to access only HTTP and HTTPS resources:
#iptables -A OUTPUT -p tcp -m multiport --dports 80,443 -o eth0 -m state --state NEW,ESTABLISHED -j ACCEPT #iptables -A INPUT -p tcp -m multiport --sports 80,443 -i eth0 -m state --state ESTABLISHED -j ACCEPT |
--------------------------------------------------------
- FACULTATIVE RULES:
If you have SSH servers on your OpenVPN machines, you can set the rules to accept the SSH traffic.
To install a SSH server, you just have to use the following command: "apt-get install openssh-server"
Rules to permit the local SSH client to access a remote SSH server.
#iptables -A OUTPUT -p tcp -o eth0 --dport 22 -s 50.0.0.1 -j ACCEPT #iptables -A INPUT -p tcp --sport 22 -i eth0 -d 50.0.0.1 -m state --state ESTABLISHED -j ACCEPT |
Rules to permit remote SSH clients to access the local SSH server.
#iptables -A INPUT -p tcp --dport 22 -i eth0 -d 50.0.0.1 -j ACCEPT #iptables -A OUTPUT -p tcp --sport 22 -o eth0 -s 50.0.0.1 -m state --state ESTABLISHED -j ACCEPT |
For connectivity checks, 50.0.0.1 and 100.0.0.1 can ping each other.
#iptables -A INPUT -p icmp -i eth0 -s 100.0.0.1 -d 50.0.0.1 -j ACCEPT #iptables -A OUTPUT -p icmp -o eth0 -d 100.0.0.1 -s 50.0.0.1 -j ACCEPT |
--------------------------------------------------------
- CHECKS
Check the FireWall table:
Chain INPUT (policy DROP 13 packets, 683 bytes) |
pkts | bytes | target | prot | opt | in | out | source | destination | |
0 | 0 | ACCEPT | udp | -- | eth0 | * | 100.0.0.1 | 50.0.0.1 | udp spt:2001 dpt:2000 |
4 | 272 | ACCEPT | 0 | -- | tap+ | * | 0.0.0.0/0 | 0.0.0.0/0 | |
0 | 0 | ACCEPT | 0 | -- | eth0 | * | 10.0.1.0/24 | 0.0.0.0/0 | |
0 | 0 | ACCEPT | tcp | -- | eth0 | * | 0.0.0.0/0 | 0.0.0.0/0 | multiport sports 80,443 state ESTABLISHED |
4 | 336 | ACCEPT | icmp | -- | eth0 | * | 100.0.0.1 | 50.0.0.1 | |
0 | 0 | ACCEPT | tcp | -- | eth0 | * | 0.0.0.0/0 | 50.0.0.1 | tcp spt:22 state ESTABLISHED |
157 | 10884 | ACCEPT | tcp | -- | eth0 | * | 0.0.0.0/0 | 50.0.0.1 | tcp dpt:22 |
| | | | | | | | | |
Chain FORWARD (policy ACCEPT 5 packets, 217 bytes) |
pkts | bytes | target | prot | opt | in | out | source | destination | |
| | | | | | | | | |
Chain OUTPUT (policy DROP 339 packets, 110K bytes) |
pkts | bytes | target | prot | opt | in | out | source | destination | |
0 | 0 | ACCEPT | udp | -- | * | eth0 | 50.0.0.1 | 100.0.0.1 | udp spt:2000 dpt:2001 |
| | ACCEPT | 0 | -- | * | tap+ | 0.0.0.0/0 | 0.0.0.0/0 | |
0 | 0 | ACCEPT | 0 | -- | * | eth0 | 0.0.0.0/0 | 10.0.1.0/24 | |
0 | 0 | ACCEPT | tcp | -- | * | eth0 | 0.0.0.0/0 | 0.0.0.0/0 | multiport dports 80,443 |
4 | 336 | ACCEPT | icmp | -- | * | eth0 | 50.0.0.1 | 100.0.0.1 | |
0 | 0 | ACCEPT | tcp | -- | * | eth0 | 50.0.0.1 | 0.0.0.0/0 | tcp dpt:22 |
173 | 22594 | ACCEPT | tcp | -- | * | eth0 | 50.0.0.1 | 0.0.0.0/0 | tcp spt:22 state ESTABLISHED |
Check the NAT table:
Chain INPUT (policy DROP 13 packets, 683 bytes) |
pkts | bytes | target | prot | opt | in | out | source | destination | |
| | | | | | | | | |
Chain FORWARD (policy ACCEPT 5 packets, 217 bytes) |
pkts | bytes | target | prot | opt | in | out | source | destination | |
108 | 9273 | MASQUERADE | 0 | - - | any | eth0 | anywhere | | |
| | | | | | | | | |
Chain OUTPUT (policy DROP 339 packets, 110K bytes) |
pkts | bytes | target | prot | opt | in | out | source | destination | |
OpenVPN Client Linux Configuration:
- RESET YOUR IPTABLES SETTINGS:
--------------------------------------------------------
- DEFAULT POLICIES:
Set the rules to deny by default all the incoming and outgoing traffics and accept the forward traffic (inter-interface routing):
#iptables -P OUTPUT DROP #iptables -P INPUT DROP #iptables -P FORWARD ACCEPT |
--------------------------------------------------------
- OPENVPN RULES:
Authorize the OpenVPN tunnel:
#iptables -A INPUT -i eth0 -p udp -s 50.0.0.1 -d 100.0.0.1 --sport 2000 --dport 2001 -j ACCEPT #iptables -A OUTPUT -o eth0 -p udp -s 100.0.0.1 -d 50.0.0.1 --sport 2001 --dport 2000 -j ACCEPT |
Authorize all the traffic inside the tunnel:
#iptables -A INPUT -i tap+ -p all -j ACCEPT #iptables -A OUTPUT -o tap+ -p all -j ACCEPT |
--------------------------------------------------------
- LAN INTERFACE
All the traffic to and from the LAN interface (eth1) is accepted:
#iptables -A INPUT -i eth1 -p all -s 10.0.2.0/24 -j ACCEPT #iptables -A OUTPUT -o eth1 -p all -d 10.0.2.0/24 -j ACCEPT |
--------------------------------------------------------
- INTERNET ACCESS:
NAT rules:
Users from the sites B networks must be able to surf on the Internet, this will imply NAT settings.
For example, when the Desktop located in site B wants to access a web page on the Internet, its source IP address is translated and takes the OpenVPN client WAN IP address. In other words, 10.0.2.100 is translated to 100.0.0.1 and vice versa when the packets come back to the Desktop.
This kind of NAT is called masquerade.
#iptables -t nat -A POSTROUTING -j MASQUERADE |
Internet access authorization:
LAN users are allowed to access only HTTP and HTTPS resources:
#iptables -A OUTPUT -p tcp -m multiport --dports 80,443 -o eth0 -j ACCEPT #iptables -A INPUT -p tcp -m multiport --sports 80,443 -i eth0 -m state --state ESTABLISHED -j ACCEPT |
--------------------------------------------------------
- FACULTATIVE RULES:
If you have SSH servers on your OpenVPN machines, you can set the rules to accept the SSH traffic.
To install a SSH server, you just have to use the following command: "apt-get install openssh-server"
Rules to permit the local SSH client to access a remote SSH server.
#iptables -A OUTPUT -p tcp -o eth0 --dport 22 -s 100.0.0.1 -j ACCEPT #iptables -A INPUT -p tcp --sport 22 -i eth0 -d 100.0.0.1 -m state --state ESTABLISHED -j ACCEPT |
Rules to permit remote SSH clients to access the local SSH server.
#iptables -A INPUT -p tcp --dport 22 -i eth0 -d 100.0.0.1 -j ACCEPT #iptables -A OUTPUT -p tcp --sport 22 -o eth0 -s 100.0.0.1 -m state --state ESTABLISHED -j ACCEPT |
For connectivity checks, 50.0.0.1 and 100.0.0.1 can ping each other.
#iptables -A INPUT -p icmp -i eth0 -s 50.0.0.1 -d 100.0.0.1 -j ACCEPT #iptables -A OUTPUT -p icmp -o eth0 -d 50.0.0.1 -s 100.0.0.1 -j ACCEPT |
7. ROUTING
Network routes
To establish the link between machines inside the LANs of site A and site B, the following routes need to be added on the Linux VPN devices.
On OpenVPN server: destination network 10.0.2.0 mask 255.255.255.0 gateway 10.7.0.6
On OpenVPN client: destination network 10.0.1.0 mask 255.255.255.0 gateway 10.7.0.1
The two routes are automatically added with our server configuration. The OpenVPN server route is added through the "route.txt" script and the OpenVPN client route is pushed by the OpenVPN server.
IP forwarding
IP forwarding is required to transfer packets between the network interfaces of a Linux system.
#echo "1" > /proc/sys/net/ipv4/ip_forward |
The command above will add the "1" value inside the /proc/sys/net/ipv4/ip_forward file and thus activate the IP forwarding.
If you want to keep the IP forwarding after a Linux reboot:
#echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf |
8. CHECKS:
The clients (10.0.1.100 and 10.0.2.100) should be able to see each other and access HTTTP or HTTPS resources on the Internet.
LAN to LAN connectivity checks:
The clients (10.0.1.100 and 10.0.2.100) should be able to see each other. The ping and traceroute commands can be used for this purpose.
From the 10.0.1.100 client which is a Linux machine:
traceroute to 10.0.2.100 (10.0.2.100), 30 hops max, 40 byte packets
1 10.0.1.1 (10.0.1.1) 0.521 ms 0.848 ms 1.011 ms
2 10.7.0.6 (10.7.0.6) 0.420 ms 0.472 ms 0505 ms
3 10.0.2.100 (10.0.2.100) 0.538 ms * *
HTTTP Internet access check:
A way to test if the IPtables firewall is set to accept HTTP (TCP port 80) and HTTPS (TCP port 443) traffic is to use a browser or simpler, the Command Line interface (CLI) is to check if the TCP 80 and TCP 443 ports are opened with the telnet client.
Trying 100.0.0.100... Connected to 100.0.0.100. Escape character is '^]'. |
Of course, we will see only a banner (Escape character is '^]'.) but this is enough to indicate that the port is opened.
Here is the result you would obtain when you test a closed port, for instance the FTP 21 port:
Route Tables:
Server:
Kernel IP routing table |
Destination | Gateway | Genmask | Flags | Metric | Ref | Use | Iface |
10.7.0.0 | 0.0.0.0 | 255.255.255.248 | U | 0 | 0 | 0 | tap0 |
10.0.1.0 | 0.0.0.0 | 255.255.255.0 | U | 0 | 0 | 0 | eth1 |
10.0.2.0 | 10.7.0.6 | 255.255.255.0 | UG | 0 | 0 | 0 | tap0 |
50.0.0.0 | 0.0.0.0 | 255.255.255.0 | U | 0 | 0 | 0 | eth0 |
0.0.0.0 | 50.0.0.100 | 0.0.0.0 | UG | 0 | 0 | 0 | eth0 |
Client:
Kernel IP routing table |
Destination | Gateway | Genmask | Flags | Metric | Ref | Use | Iface |
10.7.0.0 | 0.0.0.0 | 255.255.255.248 | U | 0 | 0 | 0 | tap0 |
10.0.2.0 | 0.0.0.0 | 255.255.255.0 | U | 0 | 0 | 0 | eth1 |
10.0.1.0 | 10.7.0.1 | 255.255.255.0 | UG | 0 | 0 | 0 | tap0 |
100.0.0.0 | 0.0.0.0 | 255.255.255.0 | U | 0 | 0 | 0 | eth0 |
0.0.0.0 | 100.0.0.100 | 0.0.0.0 | UG | 0 | 0 | 0 | eth0 |
TCPdump
TCPdump is used below to check the traffic inside the OpenVPN tunnel in the first example and on the port 2000 of the Linux WAN interface in the second example. Both examples are performed on the OpenVPN server.
- n: numeric
- i: interface
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on tap0, link-type EN10MB (Ethernet), capture size 96 bytes IP 10.7.0.1 > 10.7.0.6: ICMP echo request, id 1824, seq 60, length 64 IP 10.7.0.6 > 10.7.0.1: ICMP echo reply, id 1824, seq 60, length 64 IP 10.7.0.1 > 10.7.0.6: ICMP echo request, id 1824, seq 61, length 64 |
#tcpdump -i eth0 port 2000 -n |
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on eth0, link-type EN10MB (Ethernet), capture size 96 bytes IP 50.0.0.1.2000 > 100.0.0.1.2001: UDP, length 145 IP 100.0.0.1.2001 > 50.0.0.1.2000: UDP, length 145 IP 50.0.0.1.2000 > 100.0.0.1.2001: UDP, length 145 IP 100.0.0.1.2001 > 50.0.0.1.2000: UDP, length 145 IP 50.0.0.1.2000 > 100.0.0.1.2001: UDP, length 145 IP 100.0.0.1.2001 > 50.0.0.1.2000: UDP, length 145 |
9. STARTUP SCRIPT
OpenVPN
The OpenVPN software is set to be launched automatically when the linux system boots.
To manually set OpenVPN to start automatically at bootup:
#update-rc.d openvpn defaults |
To prevent OpenVPN to start automatically at bootup:
#update-rc.d -f openvpn remove |
IPtables
The IPtables commands need to be added in a file called "iptables.sh" which will be executed when the Linux system boots.
The file is stored in the /root directory.
Add a line inside the /etc/crontab file to start the IPtables commands automatically after a reboot:
@reboot root /root/iptables.sh >> /dev/null |
- OpenVPN server file.
/home/root/iptables.sh
# OpenVPN server IPtables settings # #RESET your IPtables settings iptables -F # #DEFAULT POLICIES: # iptables -P OUTPUT DROP iptables -P INPUT DROP iptables -P FORWARD ACCEPT # #Authorize the OpenVPN tunnel: # iptables -A INPUT -i eth0 -p udp -s 100.0.0.1 -d 50.0.0.1 --sport 2001 --dport 2000 -j ACCEPT iptables -A OUTPUT -o eth0 -p udp -s 50.0.0.1 -d 100.0.0.1 --sport 2000 --dport 2001 -j ACCEPT # #Authorize all the traffic inside the tunnel: # iptables -A INPUT -i tap+ -p all -j ACCEPT iptables -A OUTPUT -o tap+ -p all -j ACCEPT # #All the traffic to and from the LAN interface (eth1) is accepted: # iptables -A INPUT -i eth1 -p all -s 10.0.1.0/24 -j ACCEPT iptables -A OUTPUT -o eth1 -p all -d 10.0.1.0/24 -j ACCEPT # #NAT rules: # iptables -t nat -A POSTROUTING -j MASQUERADE # #LAN users are allowed to access only Internet HTTP and HTTPS resources: # iptables -A OUTPUT -p tcp -m multiport --dports 80,443 -o eth0 -j ACCEPT iptables -A INPUT -p tcp -m multiport --sports 80,443 -i eth0 -m state --state ESTABLISHED -j ACCEPT # # FACULTATIVE RULES: # #Rules to permit the local SSH client to access a remote SSH server # iptables -A OUTPUT -p tcp -o eth0 --dport 22 -s 50.0.0.1 -j ACCEPT iptables -A INPUT -p tcp --sport 22 -i eth0 -d 50.0.0.1 -m state --state ESTABLISHED -j ACCEPT # # Rules to permit remote SSH clients to access the local SSH server # iptables -A INPUT -p tcp --dport 22 -i eth0 -d 50.0.0.1 -j ACCEPT iptables -A OUTPUT -p tcp --sport 22 -o eth0 -s 50.0.0.1 -m state --state ESTABLISHED -j ACCEPT # #For connectivity checks, 50.0.0.1 and 100.0.0.1 can ping each other. # iptables -A INPUT -p icmp -i eth0 -s 100.0.0.1 -d 50.0.0.1 -j ACCEPT iptables -A OUTPUT -p icmp -o eth0 -d 100.0.0.1 -s 50.0.0.1 -j ACCEPT |
- OpenVPN client file.
/home/root/iptables.sh
# OpenVPN client IPtables settings # #RESET your IPtables settings iptables -F # #DEFAULT POLICIES: # iptables -P OUTPUT DROP iptables -P INPUT DROP iptables -P FORWARD ACCEPT # #Authorize the OpenVPN tunnel: # iptables -A INPUT -i eth0 -p udp -s 50.0.0.1 -d 100.0.0.1 --sport 2000 --dport 2001 -j ACCEPT iptables -A OUTPUT -o eth0 -p udp -s 100.0.0.1 -d 50.0.0.1 --sport 2001 --dport 2000 -j ACCEPT # #Authorize all the traffic inside the tunnel: # iptables -A INPUT -i tap+ -p all -j ACCEPT iptables -A OUTPUT -o tap+ -p all -j ACCEPT # #All the traffic to and from the LAN interface (eth1) is accepted: # iptables -A INPUT -i eth1 -p all -s 10.0.2.0/24 -j ACCEPT iptables -A OUTPUT -o eth1 -p all -d 10.0.2.0/24 -j ACCEPT # #NAT rules: # iptables -t nat -A POSTROUTING -j MASQUERADE # #LAN users are allowed to access only Internet HTTP and HTTPS resources: # iptables -A OUTPUT -p tcp -m multiport --dports 80,443 -o eth0 -j ACCEPT iptables -A INPUT -p tcp -m multiport --sports 80,443 -i eth0 -m state --state ESTABLISHED -j ACCEPT # # FACULTATIVE RULES: # #Rules to permit the local SSH client to access a remote SSH server # iptables -A OUTPUT -p tcp -o eth0 --dport 22 -s 100.0.0.1 -j ACCEPT iptables -A INPUT -p tcp --sport 22 -i eth0 -d 100.0.0.1 -m state --state ESTABLISHED -j ACCEPT # # Rules to permit remote SSH clients to access the local SSH server # iptables -A INPUT -p tcp --dport 22 -i eth0 -d 100.0.0.1 -j ACCEPT iptables -A OUTPUT -p tcp --sport 22 -o eth0 -s 100.0.0.1 -m state --state ESTABLISHED -j ACCEPT # #For connectivity checks, 50.0.0.1 and 100.0.0.1 can ping each other. # iptables -A INPUT -p icmp -i eth0 -s 50.0.0.1 -d 100.0.0.1 -j ACCEPT iptables -A OUTPUT -p icmp -o eth0 -d 50.0.0.1 -s 100.0.0.1 -j ACCEPT |
-------------------------------------
The very last thing to do is to set the /root/iptables.sh file permission.
The user root has read/write/execute permissions. None else has any permissions at all.
#chmod 700 /root/iptables.sh |
The user root is the owner of the /root/iptables.sh file.
#chown root /root/iptables.sh |