📜 ⬆️ ⬇️

How-to VPN (pptpd + mysql + radius) on CentOS6

image Although how-to articles are not very commented, and mostly not with positive comments, however, it is them that are most of all added to bookmarks.
Here I will try to describe the process of installing and configuring a VPN server on CentOS6 with users in MySQL and authorization over a radius for an encrypted connection using ms-chap-v2 and mppe.

Preamble

Where do these articles come from? It's simple. When we are looking for job seekers, for example, for the post of system administrator, after selecting candidates for a preliminary interview, test tasks are compiled, implemented on their own, and then we suggest that they be solved by the applicants. For the execution of tasks, the applicant is provided with a virtual machine, Internet access, and a certain time. Time is calculated simply - our implementation * 2. At the same time, you can assume that all the necessary solutions (how-to) can be found on the Internet, however, we take this into account and therefore do not take ready-made solutions, but compile and decide them in advance on fresh distributors. By the way, there are cases when we stumble upon certain problems in the implementation (small undocumented developer pranks), and if the candidate is on the right course, but gets stuck on this particular problem, we suggest what we found, its solution.


Given

KVM virtual machine with white IP and freshly installed CentOS6 x86_64 minimal.
')
Task

1. Install and configure in conjunction pptpd, freeradius2, radiusclient-ng and mysql.
2. Create 2 clients to connect to the configured VPN-server, with access to no NAT status. One client with a dynamic address retrieval, the second with a constant IP.
3. Transfer the pool of addresses to distribute to dynamic clients from pptpd to radius.

Decision

The first step is to install all the necessary packages. radiusclient-ng and pptpd are not in standard repositories, therefore for radiusclient-ng we will connect the EPEL repository, and we will download the pptpd-package directly.
# rpm -Uhv fedora-epel.mirror.lstn.net/6/x86_64/epel-release-6-5.noarch.rpm
# yum install freeradius freeradius-mysql radiusclient-ng radiusclient-ng-utils freeradius-utils mysql mysql-devel mysql-server
#rpm -Uhv poptop.sourceforge.net/yum/stable/packages/pptpd-1.3.4-2.el6.x86_64.rpm


further we will configure mysql and we will set the password:
mysql_secure_installation

Actually proceed to configure pptpd. Here are the configuration files as follows:
# cat /etc/pptpd.conf
option /etc/ppp/options.pptpd
logwtmp
localip 192.168.80.1
remoteip 192.168.80.5-35


# cat /etc/ppp/options.pptpd
name pptpd
refuse-pap
refuse-chap
refuse-mschap
require-mschap-v2
require-mppe-128
proxyarp
lock
nobsdcomp
novj
novjccomp
nologfd
plugin radius.so
plugin radattr.so


with pptpd is finished, go to the radiusclient-ng setup:

The first problem we encountered was the reluctance of pptpd to work with radiusclient-ng because of the paths to where it is installed, therefore we create a soft link as follows
# ln -s /etc/radiusclient-ng /etc/radiusclient
and comment out the line in /etc/radiusclient-ng/radiusclient.conf
#bindaddr *
otherwise swears at an unknown parameter.
edit / etc / radiusclient-ng / servers, add a local radius server that the client will contact
localhost YouRsUpErpAAs

The second problem we faced was the absence of mircosoft attributes in the radiusclient-ng package; after googling, the necessary artifacts were found. Copy existing files with attributes from / usr / share / radiusclient-ng / to / etc / radiusclient-ng /
# cp /usr/share/radiusclient-ng/diction* /etc/radiusclient-ng/
in / etc / radiusclient-ng / create a dictionary.microsoft file with the following contents:
VENDOR Microsoft 311 Microsoft

ATTRIBUTE MS-CHAP-Response 1 string Microsoft
ATTRIBUTE MS-CHAP-Error 2 string Microsoft
ATTRIBUTE MS-CHAP-CPW-1 3 string Microsoft
ATTRIBUTE MS-CHAP-CPW-2 4 string Microsoft
ATTRIBUTE MS-CHAP-LM-Enc-PW 5 string Microsoft
ATTRIBUTE MS-CHAP-NT-Enc-PW 6 string Microsoft
ATTRIBUTE MS-MPPE-Encryption-Policy 7 string Microsoft
ATTRIBUTE MS-MPPE-Encryption-Type 8 string Microsoft
ATTRIBUTE MS-MPPE-Encryption-Types 8 string Microsoft
ATTRIBUTE MS-RAS-Vendor 9 integer Microsoft
ATTRIBUTE MS-CHAP-Domain 10 string Microsoft
ATTRIBUTE MS-CHAP-Challenge 11 string Microsoft
ATTRIBUTE MS-CHAP-MPPE-Keys 12 string Microsoft
ATTRIBUTE MS-BAP-Usage 13 integer Microsoft
ATTRIBUTE MS-Link-Utilization-Threshold 14 integer Microsoft
ATTRIBUTE MS-Link-Drop-Time-Limit 15 integer Microsoft
ATTRIBUTE MS-MPPE-Send-Key 16 string Microsoft
ATTRIBUTE MS-MPPE-Recv-Key 17 string Microsoft
ATTRIBUTE MS-RAS-Version 18 string Microsoft
ATTRIBUTE MS-Old-ARAP-Password 19 string Microsoft
ATTRIBUTE MS-New-ARAP-Password 20 string Microsoft
ATTRIBUTE MS-ARAP-PW-Change-Reason 21 integer Microsoft
ATTRIBUTE MS-Filter 22 string Microsoft
ATTRIBUTE MS-Acct-Auth-Type 23 integer Microsoft
ATTRIBUTE MS-Acct-EAP-Type 24 integer Microsoft
ATTRIBUTE MS-CHAP2-Response 25 string Microsoft
ATTRIBUTE MS-CHAP2-Success 26 string Microsoft
ATTRIBUTE MS-CHAP2-CPW 27 string Microsoft
ATTRIBUTE MS-Primary-DNS-Server 28 ipaddr Microsoft
ATTRIBUTE MS-Secondary-DNS-Server 29 ipaddr Microsoft
ATTRIBUTE MS-Primary-NBNS-Server 30 ipaddr Microsoft
ATTRIBUTE MS-Secondary-NBNS-Server 31 ipaddr Microsoft
VALUE MS-BAP-Usage Not-Allowed 0
VALUE MS-BAP-Usage Allowed 1
VALUE MS-BAP-Usage Required 2
VALUE MS-ARAP-PW-Change-Reason Just-Change-Password 1
VALUE MS-ARAP-PW-Change-Reason Expired-Password 2
VALUE MS-ARAP-PW-Change-Reason Admin-Requires-Password-Change 3
VALUE MS-ARAP-PW-Change-Reason Password-Too-Short 4
VALUE MS-Acct-Auth-Type PAP 1
VALUE MS-Acct-Auth-Type CHAP 2
VALUE MS-Acct-Auth-Type MS-CHAP-1 3
VALUE MS-Acct-Auth-Type MS-CHAP-2 4
VALUE MS-Acct-Auth-Type EAP 5
VALUE MS-Acct-EAP-Type MD5 4
VALUE MS-Acct-EAP-Type OTP 5
VALUE MS-Acct-EAP-Type Generic-Token-Card 6
VALUE MS-Acct-EAP-Type TLS 13


edit the file /etc/radiusclient-ng/radiusclient.conf on the subject
dictionary /etc/radiusclient-ng/dictionary

edit the file / etc / radiusclient-ng / dictionary, adding to the end
INCLUDE /etc/radiusclient-ng/dictionary.microsoft
INCLUDE /etc/radiusclient-ng/dictionary.merit


with the client also finished, go to the mysql configuration:
the freeradius-mysql package contains the necessary files for importing them into mysql, they are located in / etc / raddb / sql / mysql /
edit the admin.sql file to set a different password than the standard one
vim admin.sql
:%s/radpass/radpass235/g
:wq

connect to mysql, create a DB, import tables and create users
mysql -p
mysql> create database radius;
mysql> \. admin.sql
mysql> use radius;
mysql> \. schema.sql

further we create users and their settings
mysql> INSERT INTO radusergroup (username,groupname) values ('user1','static-ip-vpn');
mysql> INSERT INTO radusergroup (username,groupname) values ('user2','dinamic-ip-vpn');

should get the following
mysql> select * from radusergroup;
+----------+----------------+----------+
| username | groupname | priority |
+----------+----------------+----------+
| user1 | static-ip-vpn | 1 |
| user2 | dinamic-ip-vpn | 1 |
+----------+----------------+----------+

mysql> INSERT INTO radcheck (username,attribute,op,value) values ('user1','User-Password','==','pass1');
mysql> INSERT INTO radcheck (username,attribute,op,value) values ('user2','User-Password','==','pass2');

mysql> select * from radcheck;
+----+----------+---------------+----+-------+
| id | username | attribute | op | value |
+----+----------+---------------+----+-------+
| 1 | user1 | User-Password | == | pass1 |
| 2 | user2 | User-Password | == | pass2 |
+----+----------+---------------+----+-------+

fill in the radgroupreply table
mysql> INSERT INTO radgroupreply (groupname, attribute, op, value) values ('dinamic-ip-vpn','Service-Type',':=','Framed-User');
and so on to get the following
mysql> select * from radgroupreply;
+----+----------------+--------------------+----+---------------------+
| id | groupname | attribute | op | value |
+----+----------------+--------------------+----+---------------------+
| 1 | dinamic-ip-vpn | Service-Type | := | Framed-User |
| 2 | dinamic-ip-vpn | Framed-Protocol | := | PPP |
| 3 | dinamic-ip-vpn | Framed-Compression | := | Van-Jacobsen-TCP-IP |
| 4 | static-ip-vpn | Framed-Compression | := | Van-Jacobsen-TCP-IP |
| 5 | static-ip-vpn | Framed-Protocol | := | PPP |
| 6 | static-ip-vpn | Service-Type | := | Framed-User |
+----+----------------+--------------------+----+---------------------+


fill in the radreply table to set a constant ip for the first client
mysql> INSERT INTO radreply (username, attribute, op, value) values ('user1','Framed-IP-Netmask',':=','255.255.255.255');
mysql> INSERT INTO radreply (username, attribute, op, value) values ('user1','Framed-IP-Address',':=','192.168.80.90');

mysql> select * from radreply;
+----+----------+-------------------+----+-----------------+
| id | username | attribute | op | value |
+----+----------+-------------------+----+-----------------+
| 1 | user1 | Framed-IP-Netmask | := | 255.255.255.255 |
| 2 | user1 | Framed-IP-Address | := | 192.168.80.90 |
+----+----------+-------------------+----+-----------------+

As a result, we added 2 clients to the database, user1 with the password pass1 and static ip - 192.168.80.90, and user2 with the password pass2 and getting a dynamic ip from the pool specified in the pptpd settings. Here, users are deliberately divided into groups, taking into account the further increase in customers, it was possible to simply create all the attributes for both clients in the radreply table, but with a large number of clients, it is more convenient to use groups that specify the same attributes for clients. Also, in groups, you can specify different pools of addresses and much more, but we will not discuss this now, because we need to solve the problem in the set time frame.

Go to the radius settings. Here I will give examples of files in which changes were made:
/etc/raddb/clients.conf
client 127.0.0.1 {
secret = YouRsUpErpAAs
shortname = localhost
nastype = other
}


The third problem , at the time of debugging, when radius was not yet connected to mysql, was faced with the fact that if clients turned out to be written in the / etc / raddb / users file not at the beginning of the file, nothing worked.

/ etc / raddb / users
DEFAULT Simultaneous-Use := 1
Fall-Through = 1

It is necessary to register it so that there are not several connections with the same login at the same time.

/etc/raddb/radiusd.conf
in the modules section, remove comments from
$INCLUDE sql.conf

/etc/raddb/sql.conf
we register data for connection to mysql
password = "radpass235"

/ etc / raddb / sites-enabled / default
in the authorize, session, post-auth and accounting sections we include sql
in the authorize section we include mschap

/ etc / raddb / modules / mschap
mschap {
use_mppe = yes
require_encryption = yes
require_strong = yes
}


Perhaps, the problem is almost solved, some strokes remain:

Configure iptables and allow the forward to release clients into the world
iptables -I INPUT -p gre -j ACCEPT
iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 1723 -j ACCEPT
iptables -I INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -I FORWARD -s 192.168.80.0/24 -o eth0 -j ACCEPT
iptables -I FORWARD -d 192.168.80.0/24 -i eth0 -j ACCEPT
iptables -t nat -I POSTROUTING -s 192.168.80.0/24 -o eth0 -j MASQUERADE


/etc/sysctl.conf
net.ipv4.ip_forward = 1
# sysctl -p


Already at this stage, if we start the installed services, we can connect to our machine via vpn, it remains only to transfer the pool of addresses issued by dynamic clients from pptpd to radius. There are several options for this, up to putting the pool in mysql. We use a simple option.

/ etc / raddb / modules / ippool
in the ippool main_pool section, edit for your address pool
range-start = 192.168.80.35
range-stop = 192.168.80.65


in the file / etc / raddb / sites-enabled / default add to the appropriate sections

accounting {
main_pool
}

post-auth {
main_pool
}


Next, create the files where the pool will be stored.
touch /etc/raddb/db.ipindex /etc/raddb/db.ippool
chmod 664 /etc/raddb/db.ipindex /etc/raddb/db.ippool
chown root:radiusd /etc/raddb/db.ipindex /etc/raddb/db.ippool


and add to / etc / raddb / users
DEFAULT Pool-Name := main_pool
Fall-Through = Yes


restart the radius, and try to connect to the machine via vpn, everything should work. We can see detailed connection statistics in the radius.radacct table
selected addresses from the pool, you can see the command:
rlm_ippool_tool -av /etc/raddbdb/db.ippool /etc/raddbdb/db.ipindex

Afterword


I deliberately stressed the problems that we had to face. We spent a little over an hour deploying this system. 2.5 hours were allocated for candidates. None of the 4 applicants completed this task in full. Only one of them has practically reached the end of the road. With him, perhaps, we will continue to cooperate.
Of course, I understand that not all employers use this method of job seekers tests. However, I think this is one of the best ways to really test the knowledge and capabilities of candidates. After all, if the candidate decided (or almost solved) a similar task, it means that after a while, joining the team and immersing in the network structure, it is quite possible to rely on it.

I could call the article “How we choose workers,” and describe the process of preliminary selection and practical assignment in general terms, but then, the article would not have its value as near-technical, and would not be in the form of how-to, but It would be less useful, in my opinion. I know that there are several similar articles here, including binding to abills, but they are more than a year and a half and they are under other distra.

UPD: Perhaps the applicants read Habr, and finally see the solution of the task they did not pass.

UPD2: Regarding the lack of time for implementation, they write that 2.5 hours is not enough. I emphasize that time is not the main , albeit a significant indicator. The main "right way".

UPD3: Inspired by comments about the slopiness of the pptp protocol. Identical with l2tp.
Instead of pptpd we put xl2tpd
#yum install xl2tpd
The configuration files are as follows:
# cat /etc/xl2tpd/xl2tpd.conf
[global]
port = 1701
auth file = /etc/xl2tpd/l2tp-secrets
access control = no
rand source = dev
[lns default]
exclusive = no
ip range = 192.168.80.5-192.168.81.35
local ip = 192.168.80.1
require chap = yes
refuse pap = yes
require authentication = yes
name = VPNserver
ppp debug = yes
pppoptfile = /etc/ppp/options.xl2tpd
length bit = yes
flow bit = yes


# cat /etc/ppp/options.xl2tpd
ipcp-accept-local
ipcp-accept-remote
lcp-echo-failure 30
lcp-echo-interval 5
noccp
nodeflate
auth
crtscts
idle 1800
mtu 1410
mru 1410
defaultroute
debug
proxyarp
connect-delay 5000
lock
plugin radius.so
plugin radattr.so

Source: https://habr.com/ru/post/128599/


All Articles