w3.nonsenz.org

VPN - PPP over SSH sous Debian / Ubuntu

Nous avons configuré notre firewall et Openssh de manière à ouvrir des sessions ssh par échange de clés. 
Comme je l'ai déjà mentionné, le wifi n'est pas très sécurisé. Notre DMZ wifi n'a pas plus de droits que les machines provenant d'Internet. Pour travailler avec plus de confort, nous allons établir un VPN entre le portable et notre firewall. Le portable pourra ainsi communiquer avec le réseau local en toute sécurité.

Comme ssh est déjà bien configuré, c'est un jeu d'enfant de réaliser une connexion ppp over ssh comme nous allons le voir.

 

schema architecture rezo

 La configuration de notre VPN va se dérouler en 3 temps.

Configuration du firewall :

Les lignes qui ont été ajoutées pour l'occasion sont en rouge.
La connexion ppp qui s'établit entre le portable Horace et le firewall Pollux reçoit le plan d'adressage 192.168.3.1 côté client et 192.168.3.2 côté serveur.

#!/bin/bash
#firewall.sh
#Passerelle
#par NonSenZ - pollux.nonsenz.org
#Usage :
#       -no pour desactiver le firewall (sur lan protege par ex.)
#       -o  permet a toutes les requetes de sortir
#                (ne protege pas contre les chevaux de Troie)
#       -a  protection maxi

#Parametres
FTP_PORTS="20:21"
HIGH_PORTS="1024:65535"
IP_SERVER_LAN="192.168.0.5"
IP_SERVER_WIFI="192.168.1.5"
IP_LAN="192.168.0.0/24"
IP_LAN_BROADCAST="192.168.0.255"
IP_WIFI="192.168.1.0/24"
IP_WIFI_BROADCAST="192.168.1.255"
IP_VPN_CLIENT="192.168.3.1"
IP_VPN_SERVER="192.168.3.2"
INET_DEV="eth0"
LAN_DEV="eth1"
WIFI_DEV="eth2"
VPN_DEV="ppp0"
IP_BITT="192.168.0.2" #hote interne bittorrent
IP_MULE="192.168.0.2" #hote interne e-mule
GM_IP_IN="192.168.0.1" #hote gnomemeeting interne
TCP_PORT_RANGE=30000:30010 #H245 si pas de tunnel
RTP_PORT_RANGE=5000:5016 #RTP connexions (2 audio, 2 video - RTP et RTCP)
TCP_LISTENING_PORT=1720 #H323
#GK_PORT_RANGE=5020:5023 #dans le cas d'une Gatekeeper

#Suivant les options - flush et politique par defaut
case $1 in
-no)
        #Vide les regles
        iptables -t filter -F
        iptables -t filter -X
        iptables -t nat -F
        iptables -t nat -X
        #Politique par defaut
        iptables -P INPUT ACCEPT
        iptables -P OUTPUT ACCEPT
        iptables -P FORWARD ACCEPT
        echo "Firewall desactive"
        exit 1
        ;;
-o)
        #Vide les regles
        iptables -t filter -F
        iptables -t filter -X
        iptables -t nat -F
        iptables -t nat -X
        #Politique par defaut
        iptables -P INPUT DROP
        iptables -P OUTPUT ACCEPT
        iptables -P FORWARD DROP
        echo "Configuration protection mini"
        ;;
-a)
        #Vide les regles
        iptables -t filter -F
        iptables -t filter -X
        iptables -t nat -F
        iptables -t nat -X
        #Politique par defaut
        iptables -P INPUT DROP
        iptables -P OUTPUT DROP
        iptables -P FORWARD DROP
        echo "Configuration protection maxi"
        ;;
*)
        echo "Argument manquant !"
        echo "Les options autoris\uffffes sont:"
        echo "-a pour une protection optimale"
        echo "-o autorise les output"
        echo "-no desactive le firewall"
        echo "$0 : ECHEC"
        exit 1
        ;;
esac

#Modules necessaires
modprobe ip_tables
modprobe ip_conntrack
modprobe ip_conntrack_ftp
modprobe ip_nat_ftp
modprobe ip_nat_irc

#Tout ce qui a ete initialise peut sortir
iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
#Tout ce qui a ete initialise peut entrer
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

#On filtre donc maintenant sur les ouvertures de connexions (state NEW)


#autorise les requetes locales
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT

############
#   LAN  -> firewall
############

#autorise les requetes du LAN
iptables -A INPUT -s $IP_LAN -d $IP_SERVER_LAN -j ACCEPT
iptables -A OUTPUT -s $IP_SERVER_LAN -d $IP_LAN -j ACCEPT
##autorise les diffusions pour les requetes dhcp
iptables -A INPUT -s 0.0.0.0/32 -d 255.255.255.255/32 -j ACCEPT
##autorise les diffusions pour samba et cups
iptables -A INPUT -s $IP_LAN -d $IP_LAN_BROADCAST -j ACCEPT
iptables -A OUTPUT -s $IP_SERVER_LAN -d $IP_LAN_BROADCAST -j ACCEPT
##autorise les requetes sur le port 123 pour ntp (heure et date)
iptables -A OUTPUT -p tcp --dport 123 -j ACCEPT
iptables -A OUTPUT -p udp --dport 123 -j ACCEPT

############
#   VPN -> firewall
############

#autorise les requetes du client VPN
iptables -A INPUT -s $IP_VPN_CLIENT -d $IP_VPN_SERVER -j ACCEPT
iptables -A OUTPUT -s $IP_VPN_SERVER -d $IP_VPN_CLIENT -j ACCEPT

#############
#  ? -> firewall
#############
#repond aux pings
iptables -A INPUT -p icmp --icmp-type destination-unreachable -j ACCEPT
iptables -A INPUT -p icmp --icmp-type time-exceeded -j ACCEPT
iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
iptables -A INPUT -p icmp --icmp-type echo-reply -j ACCEPT
#Services locaux
iptables -A INPUT -p tcp --dport ssh -j ACCEPT
iptables -A INPUT -p tcp --dport http -j ACCEPT
iptables -A INPUT -p tcp --dport https -j ACCEPT
iptables -A INPUT -p tcp -s $IP_LAN --dport 10000 -j ACCEPT
##FTP
#Autorise la connexion FTP
iptables -A INPUT -p tcp --dport $FTP_PORTS -j ACCEPT
#FTP actif
iptables -A OUTPUT -p tcp --sport $FTP_PORTS -j ACCEPT
#FTP passif
iptables -A INPUT  -p tcp --sport $HIGH_PORTS --dport $HIGH_PORTS -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A OUTPUT -p tcp --sport $HIGH_PORTS --dport $HIGH_PORTS -m state --state ESTABLISHED,RELATED -j ACCEPT
##samba     #inutile si tout est accepte sur le LAN
#iptables -A INPUT -p udp -s $IP_LAN -d $IP_SERVER_LAN -m multiport --dports 137,138 -j ACCEPT
#iptables -A INPUT -p tcp -s $IP_LAN -d $IP_SERVER_LAN -m multiport --dports 139,445 -j ACCEPT
#iptables -A INPUT -p udp -s $IP_LAN -d $IP_LAN_BROADCAST --dport 137 -j ACCEPT
##DNS       #inutile si tout est accepte sur le LAN
#iptables -A INPUT -s $IP_LAN -d $IP_SERVER_LAN -p tcp --dport 53 -j ACCEPT
#iptables -A INPUT -s $IP_LAN -d $IP_SERVER_LAN -p udp --dport 53 -j ACCEPT
#utile si un resolver (DNS) est installe sur la passerelle
iptables -A OUTPUT -p tcp --dport 53 -j ACCEPT
iptables -A OUTPUT -p udp --dport 53 -j ACCEPT


#FORWARD - Fait suivre certaines requetes vers des clients
##bittorrent
iptables -A FORWARD -p TCP --dport 6881 -j ACCEPT
iptables -A PREROUTING -t nat -p tcp --dport 6881 -j DNAT --to-destination $IP_BITT:6881
##emule
iptables -A FORWARD -p TCP --dport 4662 -j ACCEPT
iptables -A PREROUTING -t nat -p tcp --dport 4662 -j DNAT --to-destination $IP_MULE:4662
##Gnomemeeting
iptables -A PREROUTING -t nat -i $INET_DEV -p tcp --dport $TCP_PORT_RANGE -j DNAT --to-dest $GM_IP_IN
iptables -A PREROUTING -t nat -i $INET_DEV -p udp --dport $RTP_PORT_RANGE -j DNAT --to-dest $GM_IP_IN
iptables -A PREROUTING -t nat -i $INET_DEV -p tcp --dport $TCP_LISTENING_PORT -j DNAT --to-dest $GM_IP_IN
iptables -A FORWARD -p tcp -i $INET_DEV --dport $TCP_PORT_RANGE -d $GM_IP_IN -j ACCEPT
iptables -A FORWARD -p udp -i $INET_DEV --dport $RTP_PORT_RANGE -d $GM_IP_IN -j ACCEPT
iptables -A FORWARD -p tcp -i $INET_DEV --dport $TCP_LISTENING_PORT -d $GM_IP_IN -j ACCEPT
###Gnomemeeting Gatekeeper
#iptables -t nat -I PREROUTING -i $OUT_DEV -p udp --dport $GK_PORT_RANGE -j DNAT --to-dest $IN_HOST
#iptables -I FORWARD -p udp -i $OUT_DEV --dport $GK_PORT_RANGE -d $IN_HOST -j ACCEPT
#iptables -I POSTROUTING -t nat -o $IN_DEV -d $IN_HOST -p udp --dport $GK_PORT_RANGE -j ACCEPT

#############
# LAN -> INET
#############
iptables -A FORWARD -i $LAN_DEV -o $INET_DEV -m state --state ! INVALID -j ACCEPT
iptables -A FORWARD -i $INET_DEV -o $LAN_DEV -m state --state ESTABLISHED,RELATED -j ACCEPT

##############
# WIFI -> INET
##############
iptables -A FORWARD -i $WIFI_DEV -o $INET_DEV -m state --state ! INVALID -j ACCEPT
iptables -A FORWARD -i $INET_DEV -o $WIFI_DEV -m state --state ESTABLISHED,RELATED -j ACCEPT

##############
# LAN -> WIFI
##############
iptables -A FORWARD -i $LAN_DEV -o $WIFI_DEV -m state --state ! INVALID -j ACCEPT
iptables -A FORWARD -i $WIFI_DEV -o $LAN_DEV -m state --state ESTABLISHED,RELATED -j ACCEPT

##############
# LAN -> VPN
##############
iptables -A FORWARD -i $LAN_DEV -o $VPN_DEV -m state --state ! INVALID -j ACCEPT
iptables -A FORWARD -i $VPN_DEV -o $LAN_DEV -m state --state ESTABLISHED,RELATED -j ACCEPT

##############
# VPN -> LAN
##############
iptables -A FORWARD -i $VPN_DEV -o $LAN_DEV -m state --state ! INVALID -j ACCEPT
iptables -A FORWARD -i $LAN_DEV -o $VPN_DEV -m state --state ESTABLISHED,RELATED -j ACCEPT

#Diverses protections et logs
iptables -A FORWARD -m state --state INVALID -m limit --limit 3/s -j LOG --log-prefix "INVALID FORWARD: "
iptables -A FORWARD -m state --state INVALID -j DROP
iptables -A FORWARD -p TCP --tcp-flags ! ALL SYN -m state --state NEW -m limit --limit 3/s -j LOG --log-prefix "FORWARD TCP sans SYN: "
iptables -A FORWARD -p TCP --tcp-flags ! ALL SYN -m state --state NEW -j DROP
iptables -A FORWARD -j LOG -m limit --limit 3/s --log-prefix "BAD FORWARD "
iptables -A FORWARD -j DROP

#NAT-Tout ce qui sort est nate avec l'adresse publique de l'interface INET
echo 1 > /proc/sys/net/ipv4/ip_forward
iptables -t nat -A POSTROUTING -o $INET_DEV -j MASQUERADE

#empeche l'IP spoofing
echo 1 > /proc/sys/net/ipv4/conf/all/rp_filter

#bloque et logue le reste
iptables -N denylog
iptables -A denylog  -m limit --limit 40/minute -j LOG --log-prefix "IPTABLES "
iptables -A denylog -j DROP
iptables -A INPUT -j denylog
#Save
iptables-save >/etc/iptables-perso.conf
echo " DONE."


 Maintenant que le firewall est configuré, on vérifie que le paquet ppp (pppd) est installé sur le client et le serveur.
N.B. : sous debian, on met en commentaire la ligne proxyarp dans le fichier /etc/ppp/options sur le client. Nous ferons un routage manuel pour atteindre le réseau local (voir script de connexion).
Par ailleurs, on vérifiera qu'un utilisateur (autre que root) peut lancer la connexion ppp (avec sudo, ajouter l'utilisateur avec visudo).

Configuration du client :

On vérifie que le client peut se connecter sans mot de passe par ssh sur le serveur. Si tel n'est pas le cas, vous pouvez vous reporter à cette page pour configurer votre authentification ssh par échange de clés.

Il reste ensuite à réaliser un script de connexion vpn-pppssh que l'on placera dans /usr/bin/ avec les droits d'exécution.
Les paramètres en gras sont à configurer suivant votre réseau.


#!/bin/sh
# /usr/local/bin/vpn-pppssh
#
# This script initiates a ppp-ssh vpn connection.
# see the VPN PPP-SSH HOWTO on http://www.linuxdoc.org for more information.
#
# revision history:
# 1.6 11-Nov-1996 miquels@cistron.nl
# 1.7 20-Dec-1999 bart@jukie.net
# 2.0 16-May-2001 bronson@trestle.com
# 2.1 23-jan-2006 anthony@nonsenz.org

#
# You will need to change these variables...
#

# The host name or IP address of the SSH server that we are
# sending the connection request to:
SERVER_HOSTNAME=pollux.nonsenz.org

# The TCP port used by sshd (usually 22)
SERVER_PORT=443

# The username on the VPN server that will run the tunnel.
# For security reasons, this should NOT be root.  (Any user
# that can use PPP can intitiate the connection on the client)
SERVER_USERNAME=nonsenz

# The VPN network interface on the server should use this address:
SERVER_IFIPADDR=192.168.3.2

# ...and on the client, this address:
CLIENT_IFIPADDR=192.168.3.1

# Lan behind vpn server uses this addresses:
LAN_NETWORK=192.168.0.0
LAN_NETMASK=255.255.255.0

# This tells ssh to use unprivileged high ports, even though it's
# running as root.  This way, you don't have to punch custom holes
# through your firewall.
LOCAL_SSH_OPTS="-P"

#
# The rest of this file should not need to be changed.
#

PATH=/usr/local/sbin:/sbin:/bin:/usr/sbin:/usr/bin:/usr/bin/X11/:

#
# required commands...
#

PPPD=/usr/sbin/pppd
SSH=/usr/bin/ssh

if ! test -f $PPPD  ; then echo "can't find $PPPD";  exit 3; fi
if ! test -f $SSH   ; then echo "can't find $SSH";   exit 4; fi

case "$1" in
  start)
    echo -n "Starting vpn to $SERVER_HOSTNAME: "
    ${PPPD} updetach noauth passive pty "sudo -u ${SERVER_USERNAME} ${SSH} ${LOCAL_SSH_OPTS} ${SERVER_HOSTNAME} -p ${SERVER_PORT} -l ${SERVER_USERNAME} -o Batchmode=yes sudo ${PPPD} nodetach notty noauth" ${CLIENT_IFIPADDR}:${SERVER_IFIPADDR}
    route add -net ${LAN_NETWORK} netmask ${LAN_NETMASK} gw ${SERVER_IFIPADDR} dev ppp0
    echo " vpn connected."
    ;;

  stop)
        echo -n "Stopping vpn to $SERVER_HOSTNAME: "
        PID=`ps ax | grep "${SSH} ${LOCAL_SSH_OPTS} ${SERVER_HOSTNAME} -p ${SERVER_PORT} -l ${SERVER_USERNAME} -o" | grep -v ' passive ' | grep -v 'grep ' | awk '{print $1}'`
        if [ "${PID}" != "" ]; then
          kill $PID
          echo "disconnected."
        else
          echo "Failed to find PID for the connection"
        fi
    ;;

  config)
    echo "SERVER_HOSTNAME=$SERVER_HOSTNAME"
    echo "SERVER_USERNAME=$SERVER_USERNAME"
    echo "SERVER_IFIPADDR=$SERVER_IFIPADDR"
    echo "CLIENT_IFIPADDR=$CLIENT_IFIPADDR"
  ;;

  *)
    echo "Usage: vpn {start|stop|config}"
    exit 1
    ;;
esac

exit 0

Pour lancer le script, sudo vpn-pppssh start et pour l'arrêter sudo vpn-pppssh stop

Normalement ça fonctionne.


nonsenz@horace:~$ sudo vpn-pppssh start
Password:
Starting vpn to pollux.nonsenz.org: Using interface ppp0
Connect: ppp0 <--> /dev/pts/2
Deflate (15) compression enabled
local  IP address 192.168.3.1
remote IP address 192.168.3.2
 vpn connected.
nonsenz@horace:~$ route -n
Table de routage IP du noyau
Destination     Passerelle      Genmask         Indic Metric Ref    Use Iface
192.168.3.2     0.0.0.0         255.255.255.255 UH    0      0        0 ppp0
192.168.1.0     0.0.0.0         255.255.255.0   U     0      0        0 eth1
192.168.0.0     192.168.3.2     255.255.255.0   UG    0      0        0 ppp0
0.0.0.0         192.168.1.5     0.0.0.0         UG    0      0        0 eth1
nonsenz@horace:~$ ping 192.168.0.1
PING 192.168.0.1 (192.168.0.1) 56(84) bytes of data.
64 bytes from 192.168.0.1: icmp_seq=1 ttl=63 time=25.8 ms
64 bytes from 192.168.0.1: icmp_seq=2 ttl=63 time=8.35 ms
64 bytes from 192.168.0.1: icmp_seq=3 ttl=63 time=1.93 ms

--- 192.168.0.1 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2001ms
rtt min/avg/max/mdev = 1.937/12.049/25.855/10.108 ms

Maintenant, un petit hack pour lancer votre vpn depuis un réseau local qui ne laisse sortir que les protocoles courants http, https et ce via un proxy http.

Enjoy !

RETOUR

 


hébergé sur Pollux