Configuring CentOS 7 as PPTP router

Anonymizers are services that provide untraceable access to the Internet. Many of them rely on VPN technologies, and the PPTP protocol is still common among theese kind of services.

PPTP has many security problems, and support for PPTP in various products are decreasing.

This article describes how to use a Linix host in your local network as a gateway. The host will connect the PPTP tunnel and share the tunnel to other hosts on the network.

To use the tunnel, simply change the default gateway on your device to the IP of the Linux host.



This guide is based on CentOS Minimal install, more specific CentOS-7-x86_64-Minimal-1810.iso. The only physical interface is ens33 (not eth0).

Since most commands below must be entered as root, this guide assumes that you have done sudo su before you start.


First, install the PPTP package.

# yum install pptp

Next, create the PPTP connection file  /etc/ppp/peers/myvpnconnection:

pty "pptp my.pptp.server.com –nolaunchpppd"
name MyPptpUsername
remotename PPTP
file /etc/ppp/options.pptp
ipparam myvpnconnection

Replace my.pptp.server.com with the name of your PPTP server, and MyPptpUsername with the username you are using to log in.

Also note that the last line is a reference to the file name itself.

Then add your password to /etc/ppp/chap-secrets:

# Secrets for authentication using CHAP
# client          serve   secret            IP addresses
MyPptpUsername    PPTP    MyPptpPassword    *

Replace MyPptpPassword with your password.

Now its time to test your connection:

# pppd call linuxconfig

Watch /var/log/messages for any errors and warnings. You will probably see something like:

pppd[32087]: LCP: timeout sending Config-Requests

If this is the case, load module nf_conntrack_pptp to support tracking for PPTP module which is required in order to correctly establish PPTP VPN connection:

# modprobe nf_conntrack_pptp

If everything is OK, you should find something like this in /var/log/messages:

localhost pppd[7974]: CHAP authentication succeeded

localhost pppd[7974]: MPPE 128-bit stateless compression enabled

localhost pppd[7974]: local  IP address

localhost pppd[7974]: remote IP address

A new interface will show up, named ppp0:

# ip address

4: ppp0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1496 qdisc pfifo_fast state UNKNOWN group default qlen 3


    inet peer scope global ppp0

        valid_lft forever preferred_lft forever

Next step is to add routing so that all outgoing traffic uses the PPTP tunnel:

# ip route add dev ppp0

Finally we turn on IP Masqerade to allow incoming traffic to be routed and NAT-ed into the tunnel. Behind the scene its all old iptables, but since this is CentOS 7, we use firewall-cmd to update the configuration.

First, we move the real interface from zone public to zone internal:

# firewall-cmd –zone=public –remove-interface=ens33

# firewall-cmd –zone=internal –add-interface=ens33

Then we add forwarding rules:

# firewall-cmd –direct –add-rule ipv4 nat POSTROUTING 0 -o ppp0 -j MASQUERADE

# firewall-cmd –direct –add-rule ipv4 filter FORWARD 0 -i ens33 -o ppp0 -j ACCEPT

# firewall-cmd –direct –add-rule ipv4 filter FORWARD 0 -i ppp0 -o ens33 -m state –state RELATED,ESTABLISHED -j ACCEPT

Now you should be able to connect through the PPTP gateway. Change the default gateway on one of your hosts and give it a try.

Connect automatically using a script

The tricky part of this solutions is to make the gateway automatically re-connect the tunnel if it is down. After trying some more advanced methods i ended up with the old fashioned crontab job.

First, create a script called /root/pptp-connect.

There are some parameters to configure:

  • IF is the name of your network Interface.
  • PROFILE is the name of your connection profile file in /etc/ppp/peers/.
  • IP is a server on the other side of the tunnel. This host will be PING-ed to see if the tunnel is up.
  • LOG is where you want to write the log file.




function log {
    D=`date "+%Y-%m-%d %T"`
    echo $D $@
    echo $D $@ >> $LOG

ping -w1 -c1 $IP > /dev/null
if [[ $? -eq 0 ]] ; then
    log Already connected.
    exit 0

log Not connected. Will try to establish connection.

/bin/pkill pppd
sleep 1
/sbin/modprobe nf_conntrack_pptp

log Dialing...

/sbin/pppd call $PROFILE

while [[ $COUNT -ne 0 ]] ; do
    log Waiting for interface ppp0... $COUNT
    ip address | grep "ppp0:" | grep -v "state DOWN" > /dev/null
    test $RESULT -eq 0 && ((COUNT = 1))
    ((COUNT = COUNT - 1))
    sleep 1

if [[ $RESULT -eq 0 ]] ; then
    log Connected!
    log FAILED! Unable to establish connection.
    exit 2

log Adding route...
ip route add dev ppp0

log Adding Firewall rules...
sysctl -w net.ipv4.ip_forward=1
firewall-cmd --zone=public --remove-interface=$IF
firewall-cmd --zone=internal --add-interface=$IF
firewall-cmd --direct --add-rule ipv4 nat POSTROUTING 0 -o ppp0 -j MASQUERADE
firewall-cmd --direct --add-rule ipv4 filter FORWARD 0 -i $IF -o ppp0 -j ACCEPT
firewall-cmd --direct --add-rule ipv4 filter FORWARD 0 -i $ppp0 -o $IF -m state --state RELATED,ESTABLISHED -j ACCEPT

log Done!

Then all you have to do is add the script to run every minute in you crontab.

* * * * * /root/pptp-connect

Lämna ett svar

Din e-postadress kommer inte publiceras. Obligatoriska fält är märkta *