How to install a VPN Server (PPTP) on Debian/Ubuntu Linux VPS

**WARNING** PPTP is insecure. It’s better and arguably easier to setup OpenVPN instead: OpenVPN setup tutorial

Low-end (cheap) VPS accounts are very popular nowadays and one of the reason is that people use them for personal VPN purposes.
There are some advantages on using a personal VPN server:
– server resources such as CPU, bandwidth are not shared among others
– you will know for certain what VPN or Internet activity logs are kept on the server (even though many public VPN providers say that they do not keep any logs on servers, you can’t really verify that)

PPTP is probably the most popular VPN protocol. Here is a short installation guide for Debian Linux (or Ubuntu).

Step 1: install pptpd

apt-get update
apt-get install pptpd

this will install bcrelay, ppp, pptpd

Step 2: configure pptpd and ppp

pico -w /etc/pptpd.conf

(or use your favorite text editor, like vim)

Add the local and remote IP pool and the end of file:

localip 10.10.0.1
remoteip 10.10.0.2-10

in the above example, the VPN server IP will be 10.10.0.1 and the clients connecting to the VPN will be assigned private IP addresses from 10.10.0.2 to 10.10.0.10. You can obviously use other IP range or different private IP addresses (ex.: 192.168.x.y)

Save the file and exit the editor. Now edit the ppp configuration file:

pico -w /etc/ppp/pptpd-options

add the following at the end of file:

name pptpd
 refuse-pap
 refuse-chap
 refuse-mschap
 require-mschap-v2
 require-mppe-128
 ms-dns 8.8.8.8
 #ms-dns 8.8.4.4
 proxyarp
 nodefaultroute
 lock
 nobsdcomp
 mtu 1490
 mru 1490

this is what you should have in the file. Notice that the ppp daemon will refuse unsecure CHAP and MSCHAP V1 authentications. MS-CHAP V2 PPTP VPN is not too safe, either, but is definitely a better option that older CHAP and MS-CHAP V1.

Now you should add the VPN account username/password to the ppp secrets file. Edit /etc/ppp/chap-secrets and add something like this:

myusername pptpd mys3cr3tpass 10.10.0.2
myfriendsuser pptpd hisp@ssword 10.10.0.3

Step 3: enable packets forwarding 

Edit /etc/sysctl.conf and enable ipv4 forwarding by un-commenting the line (removing the # sign) and changing 0 to 1 so it looks like this:

net.ipv4.ip_forward=1

Save & exit the editor, then run:

sysctl -p

for the changes to take effect.

Add the iptables rule to create the NAT between eth0 and ppp interfaces:

iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
iptables -A FORWARD -i eth0 -o ppp0 -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -i ppp0 -o eth0 -j ACCEPT

Note that iptables MASQUERADE doesn’t work on OpenVZ VPS containers. Works on KVM and XEN.

If you use OpenVZ, you need to use iptables SOURCE like this:

iptables -t nat -A POSTROUTING -j SNAT --to-source <Public Server IP>

now restart pptpd by running:

service pptpd restart

that’s all. Now you should test the connection.

21 thoughts on “How to install a VPN Server (PPTP) on Debian/Ubuntu Linux VPS”

  1. I’m so irritated with this stuff, it can never just work for once, ubuntu tutorials can never ever just work for once could you maybe install this on my ssh ubuntu server for me?

    [email protected]

    Reply
  2. Also…

    iptables -A FORWARD -i eth0 -o ppp0 -m state -state RELATED, ESTABLISHED -j ACCEPT

    should be…

    iptables -A FORWARD -i eth0 -o ppp0 -m state –state RELATED,ESTABLISHED -j ACCEPT

    Reply
  3. Also…the -state should be changed to –state

    iptables -A FORWARD -i eth0 -o ppp0 -m state -state RELATED, ESTABLISHED -j ACCEPT

    should be…

    iptables -A FORWARD -i eth0 -o ppp0 -m state -–state RELATED,ESTABLISHED -j ACCEPT

    Reply
  4. Hi
    The last days I followed the tutorial that you expose in the web named: “How To Setup Your Own VPN With PPTP.
    In my case I configure the chap encryption and it worked ok. But when I try to configure pap encryption I never connect. Why?
    My configuration is:
    in /etc/pptpd.conf
    localip 192.168.20.9
    remoteip 192.168.20.30-40

    hostname in my server = server
    external ip 192.168.0.25
    hostname in my client = client
    external ip 192.168.0.232

    the /etc/ppp/pap-secret in my server is:
    server client 123456 *
    client server 123456 *
    the /etc/ppp/pap-secret in my client is:
    server client 123456 *
    client server 123456 *

    net.ipv4.ip_forward = 1
    iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE && iptables-save

    iptables –table nat –append POSTROUTING –out-interface ppp0 -j MASQUERADE
    iptables -I INPUT -s 192.168.20.0/24 -i ppp0 -j ACCEPT
    iptables –append FORWARD –in-interface eth0 -j ACCEPT

    the log show me this:
    Jan 30 11:44:11 client NetworkManager[1041]: SCPlugin-Ifupdown: devices removed (path: /sys/devices/virtual/net/ppp0, iface: ppp0)
    Jan 30 11:44:11 client pptp[3647]: nm-pptp-service-3631 log[pptp_read_some:pptp_ctrl.c:544]: read returned zero, peer has closed
    Jan 30 11:44:11 client pptp[3647]: nm-pptp-service-3631 log[callmgr_main:pptp_callmgr.c:258]: Closing connection (shutdown)
    Jan 30 11:44:11 client pptp[3647]: nm-pptp-service-3631 log[ctrlp_rep:pptp_ctrl.c:251]: Sent control packet type is 12 ‘Call-Clear-Request’
    Jan 30 11:44:11 client pptp[3647]: nm-pptp-service-3631 log[pptp_read_some:pptp_ctrl.c:544]: read returned zero, peer has closed
    Jan 30 11:44:11 client pptp[3647]: nm-pptp-service-3631 log[call_callback:pptp_callmgr.c:79]: Closing connection (call state)
    Jan 30 11:44:11 client NetworkManager[1041]: VPN plugin failed: 1
    Jan 30 11:44:11 client pppd[3635]: Exit.
    Jan 30 11:44:11 client NetworkManager[1041]: VPN plugin state changed: stopped (6)
    Jan 30 11:44:11 client NetworkManager[1041]: VPN plugin state change reason: 0
    Jan 30 11:44:11 client NetworkManager[1041]: error disconnecting VPN: Could not process the request because no VPN connection was active.

    I appreciated any help

    Reply
      • Hi
        I used pap because I have to send the user and password over stunnel from a specific ip phone. This phone don’t permit change the ppp protocol to chap, then I have to configure pap in my linux server.
        My pptpd-option file is:
        # Authentication

        # Name of the local system for authentication purposes
        # (must match the second field in /etc/ppp/chap-secrets entries)
        name pptpd

        # Optional: domain name to use for authentication
        # domain mydomain.net

        # Strip the domain prefix from the username before authentication.
        # (applies if you use pppd with chapms-strip-domain patch)
        #chapms-strip-domain

        # Encryption
        # Debian: on systems with a kernel built with the package
        # kernel-patch-mppe >= 2.4.2 and using ppp >= 2.4.2, …
        # {{{
        # Require the peer to authenticate itself using MS-CHAPv2 [Microsoft
        # Challenge Handshake Authentication Protocol, Version 2] authentication.
        require-mschap-v2
        # Require MPPE 128-bit encryption
        # (note that MPPE requires the use of MSCHAP-V2 during authentication)
        require-mppe-128
        # }}}

        # Network and Routing

        # If pppd is acting as a server for Microsoft Windows clients, this
        # option allows pppd to supply one or two DNS (Domain Name Server)
        # addresses to the clients. The first instance of this option
        # specifies the primary DNS address; the second instance (if given)
        # specifies the secondary DNS address.
        # Attention! This information may not be taken into account by a Windows
        # client. See KB311218 in Microsoft’s knowledge base for more information.
        #ms-dns 10.0.0.1
        #ms-dns 10.0.0.2

        # If pppd is acting as a server for Microsoft Windows or “Samba”
        # clients, this option allows pppd to supply one or two WINS (Windows
        # Internet Name Services) server addresses to the clients. The first
        # instance of this option specifies the primary WINS address; the
        # second instance (if given) specifies the secondary WINS address.
        #ms-wins 10.0.0.3
        #ms-wins 10.0.0.4

        # Add an entry to this system’s ARP [Address Resolution Protocol]
        # table with the IP address of the peer and the Ethernet address of this
        # system. This will have the effect of making the peer appear to other
        # systems to be on the local ethernet.
        # (you do not need this if your PPTP server is responsible for routing
        # packets to the clients — James Cameron)
        proxyarp

        # Debian: do not replace the default route
        nodefaultroute

        # Logging

        # Enable connection debugging facilities.
        # (see your syslog configuration for where pppd sends to)
        #debug

        # Print out all the option values which have been set.
        # (often requested by mailing list to verify options)
        #dump

        # Miscellaneous

        # Create a UUCP-style lock file for the pseudo-tty to ensure exclusive
        # access.
        lock

        # Disable BSD-Compress compression
        nobsdcomp
        require-pap
        require-chap

        Reply
        • you use require-chap, require-mschap-v2 and require-pap at the same time. I don’t think you can require all three but only one of them. Try commenting the chap and mschap-v2 and restart pptp then try again.

          Reply
          • Really I need help with this.
            I continue with the conection problem with pap. THe chap protocol worked but pap not.
            Well, I simplified the file option in both computer, server and client but didn’t work.
            I disabled chap-require like you said
            I have differnet question:

            1. I have one server and one client computer. What files, must I confgurer in both? pap-secrets?. options? options-pptpd? pptpd-options?

            2. If I configurer the user mat in the client for pap-secrets, I have to configure in the server also?

            3.

            asyncmap 0
            crtscts
            lock
            modem
            noipdefault
            -detach
            name mat
            user mat
            require-pap
            proxyarp
            #ms-dns 10.0.0.1
            idle 120

            In both computer server and client the file pap-secrets

            # Every regular user can use PPP and has to use passwords from /etc/passwd
            * hostname “” *

            # OUTBOUND connections

            # Here you should add your userid password to connect to your providers via
            # PAP. The * means that the password is to be used for ANY host you connect
            # to. Thus you do not have to worry about the foreign machine name. Just
            # replace password with your password.
            # If you have different providers with different passwords then you better
            # remove the following line.

            # * password
            mat pptpd 123456 *

            In the server. I never modified in client
            the file options.pptpd

            root@pptpd:/etc/ppp# cat options.pptp
            ###############################################################################
            # $Id: options.pptp,v 1.3 2006/03/26 23:11:05 quozl Exp $
            #
            # Sample PPTP PPP options file /etc/ppp/options.pptp
            # Options used by PPP when a connection is made by a PPTP client.
            # This file can be referred to by an /etc/ppp/peers file for the tunnel.
            # Changes are effective on the next connection. See “man pppd”.
            #
            # You are expected to change this file to suit your system. As
            # packaged, it requires PPP 2.4.2 or later from http://ppp.samba.org/
            # and the kernel MPPE module available from the CVS repository also on
            # http://ppp.samba.org/, which is packaged for DKMS as kernel_ppp_mppe.
            ###############################################################################

            # Lock the port
            lock

            # Authentication
            # We don’t need the tunnel server to authenticate itself
            noauth

            # We won’t do PAP, EAP, CHAP, or MSCHAP, but we will accept MSCHAP-V2
            # (you may need to remove these refusals if the server is not using MPPE)
            #refuse-pap
            #refuse-eap
            #refuse-chap
            #refuse-mschap

            # Compression
            # Turn off compression protocols we know won’t be used
            nobsdcomp
            nodeflate

            # Encryption
            # (There have been multiple versions of PPP with encryption support,
            # choose with of the following sections you will use. Note that MPPE
            # requires the use of MSCHAP-V2 during authentication)

            # http://ppp.samba.org/ the PPP project version of PPP by Paul Mackarras
            # ppp-2.4.2 or later with MPPE only, kernel module ppp_mppe.o
            # {{{
            # Require MPPE 128-bit encryption
            require-mppe-128
            # }}}

            # http://polbox.com/h/hs001/ fork from PPP project by Jan Dubiec
            # ppp-2.4.2 or later with MPPE and MPPC, kernel module ppp_mppe_mppc.o
            # {{{
            Require MPPE 128-bit encryption
            #mppe required,stateless
            # }}}

            the file pptpd-options in the server

            ##############################################################################
            # $Id$
            #
            # Sample Poptop PPP options file /etc/ppp/pptpd-options
            # Options used by PPP when a connection arrives from a client.
            # This file is pointed to by /etc/pptpd.conf option keyword.
            # Changes are effective on the next connection. See “man pppd”.
            #
            # You are expected to change this file to suit your system. As
            # packaged, it requires PPP 2.4.2 and the kernel MPPE module.
            ###############################################################################

            # Authentication

            # Name of the local system for authentication purposes
            # (must match the second field in /etc/ppp/chap-secrets entries)
            name pptpd

            # Optional: domain name to use for authentication
            # domain mydomain.net

            # Strip the domain prefix from the username before authentication.
            # Strip the domain prefix from the username before authentication.
            # (applies if you use pppd with chapms-strip-domain patch)
            #chapms-strip-domain

            # Encryption
            # Debian: on systems with a kernel built with the package
            # kernel-patch-mppe >= 2.4.2 and using ppp >= 2.4.2, …
            # {{{
            # Require the peer to authenticate itself using MS-CHAPv2 [Microsoft
            # Challenge Handshake Authentication Protocol, Version 2] authentication.
            require-mschap-v2
            # Require MPPE 128-bit encryption
            # (note that MPPE requires the use of MSCHAP-V2 during authentication)
            require-mppe-128
            # }}}

            #ms-dns 10.0.0.1
            #ms-dns 10.0.0.2

            #ms-wins 10.0.0.3
            #ms-wins 10.0.0.4

            proxyarp

            # Debian: do not replace the default route
            nodefaultroute

            # Logging

            # Enable connection debugging facilities.
            # (see your syslog configuration for where pppd sends to)
            #debug

            # Print out all the option values which have been set.

            # Print out all the option values which have been set.
            # (often requested by mailing list to verify options)
            #dump

            # Miscellaneous

            # Create a UUCP-style lock file for the pseudo-tty to ensure exclusive
            # access.
            lock

            # Disable BSD-Compress compression
            #nobsdcomp
            require-pap
            #require-chap

            Reply
  5. I’m using OpenVZ and everytime I run
    iptables -t nat -A POSTROUTING -j SNAT –to-source

    I get:
    -bash: syntax error near unexpected token `newline’

    When I put the server IP in it says
    # iptables -t nat -A POSTROUTING -j SNAT .to-source XXX.XX.XX.XX
    Bad argument `.to-source’
    Try `iptables -h’ or ‘iptables –help’ for more information.

    Reply
  6. Thanks, after trying different options for the past 3 days I have finally configured it correctly. My main problem was iptables rule , which you have included in here. I am on OpenVZ and I was using MASQUERADE instead of -j SNAT –source.
    Finally everything is working fine now

    Reply
  7. I have tried follow this step and already connected to vpn, the problem is the vpn status is no internet connection..

    any one can help me…

    Thanks before…

    Reply
    • martin
      October 23, 2014 at 11:17 am

      I have tried follow this step and already connected to vpn, the problem is the vpn status is no internet connection..

      any one can help me…

      Thanks before…

      you could doing this:
      pico -w /etc/pptpd.conf
      localip 10.10.0.1
      remoteip 10.10.0.2-10

      pico -w /etc/network/interfaces
      iface eth1 inet static
      address 10.10.0.1
      netmask 255.255.0.0

      pico -w /etc/ppp/pptpd-options
      ms-dns 8.8.8.8
      ms-dns 8.8.4.4

      Reply
  8. hello friends
    i have this problem
    The remote connection was not made because the attempted VPN tunnels failed. The VPN server might be unreachable. If this connection is attempting to use an L2TP/IPsec tunnel, the security parameters required for IPsec negotiation might not be configured properly.

    and what is the next step after
    service pptpd restart
    Starting PPTP Daemon: ?

    Reply

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.