-
Notifications
You must be signed in to change notification settings - Fork 28
A flexible OpenVPN plugin to handle user using a MySQL database backend
License
chantra/openvpn-mysql-auth
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
Dependencies: ------------ Debian: libmysql-client-dev libtool CentOS: mysql-devel libtool Installation: ------------- ./autogen.sh ./configure make make install Optionally, if you only ran make, you can copy the .so files from src/.libs/ like: $ sudo mkdir /etc/openvpn/mysql-auth $ sudo cp -a src/.libs/libopenvpn-mysql-auth.so* /etc/openvpn/mysql-auth/ Then add the following line to your openvpn config file: plugin /etc/openvpn/mysql-auth/libopenvpn-mysql-auth.so -c /etc/openvpn/mysql-auth/mysql-auth.conf Options: -------- 1) openvpn config file You can pass options to libopenvpn-mysql-auth.so: -c /path/to/config default: mysql-auth.conf within openvpn directory (will depend on --cd argument passed to openvpn) -d enable debugging info, default: no 2) mysql-auth.conf The configuration must follow this rule: option value Available Options: ++++++++++++++++++ DB connection infos: Required: --------- hostname hostname to connect to (or "none" if using unix socket) port port to connect to, default 0 (will connect to MySQL standard port) login username used to establish connection to DB password password used to establish connection to DB db database to conenct to s_path path to unix socket (or "none" if using TCP connection) either hostname or s_path can be omitted, but at least one of them need to be set. Once this is done, you will need to set the following option to authenticate users, check access permissions, set up firewall rule, log connections.... There are all optional, and will enable different features if there are set or not. In order to make this plugin as flexible as possible so it can adapt to any existing databases, *expandable variable* are available, see below Authentication: --------------- User/Password authentication is done if at least *auth_user_pass_verify_query* is set up. It goes through 3 steps: - check user/password - check user is allowed to access (if auth_user_pass_verify_user_access_query exists) - if not yet allowed, check if groups the user belong to is allowed to access (auth_user_pass_verify_group_access_query) * auth_user_pass_verify_query Query to check if user/password matches. To succeed, 1 and only 1 row must be returned. The value of 1st field in row will be used as {{user_id}} expandable variable ex: SELECT id FROM users WHERE username={{escaped_username}} AND password=SHA1('{{escaped_password}}') * auth_user_pass_verify_user_access_query After a user is authenticated, this query will check if the user is allowed to access the service. If omitted, no user_access check will be performed. Access will be granted if at least 1 row is returned ex: SELECT access_id FROM user_access WHERE user_access.user_id = {{user_id}} * auth_user_pass_verify_group_access_query Same as above, but for groups. Will only be called: if defined and user access did not succeed OR if defined and user_access_query was not defined Packet Filtering: ---------------- Packet filtering can be enabled in 2 manners: 1) using a single query to get default clients/subnets rules and clients/subnets rules 2) using a query for each item needed, namely default clients rules, default subnets rules, clients rules, subnets rules 1) is used if enable_pf_user_rules_query or enable_pf_group_rules_query is defined 2) is used if: - enable_pf_clients_user_default_rules_query, enable_pf_subnets_user_default_rules_query, enable_pf_clients_user_rules_query AND enable_pf_subnets_user_rules_query are defined OR - enable_pf_clients_group_default_rules_query, enable_pf_subnets_group_default_rules_query, enable_pf_clients_group_rules_query AND enable_pf_subnets_group_rules_query are defined If either enable_pf_user_rules_query or enable_pf_group_rules_query is defined, query from 2) will not be tried. When resolving the rules that apply to a specific VPN connection, during auth-user-pass-verify, the plugin will first attempt to get the rules from the *user* rules, If it did not succeed, the plugin will try the rules for the *group* . Finally, if after this, the plugin did not manage to get rules for that specific connections, the default values from default_pf_rules_clients, default_pf_rules_subnets, pf_rules_clients, pf_rules_subnets will be used. By default, these options have the following default: default_pf_rules_clients (DROP) default_pf_rules_subnets (DROP) pf_rules_clients (NULL) pf_rules_subnets (NULL) Here are the options that are available for packet filtering: - Service wide: * default_pf_rules_clients If no default client behaviour for this specific connection could be found, this value will be used. Accepted values: ACCEPT,DROP Default: DROP * default_pf_rules_subnets If no default subnets behaviour for this specific connection could be found, this value will be used. Accepted values: ACCEPT,DROP Default: DROP * pf_rules_clients If no clients rules for this specific connection could be found this will be used Accepted value: any text that follow Packet Filtering grammar (see below) Default: NULL * pf_rules_subnets If no subnets rules for this specific connection could be found this will be used Accepted value: any text that follow Packet Filtering grammar (see below) Default: NULL - Single query enable_pf_user_rules_query Query that will retrieve PF rules for that connection. The 4 first fields of MySQL results will be used and must follow this order: default_clients_rule, default_subnets_rule, clients_rules, subnets_rules Ex: SELECT f.default_clients, f.default_subnets, f.rules_clients, f.rules_subnets FROM firewall_rules f, user_firewall_rules uf WHERE f.firewall_rule_id=uf.firewall_rule_id AND uf.user_id={{user_id}} enable_pf_group_rules_query Query that will retrieve PF rules for that connection. The 4 first fields of MySQL results will be used and must follow this order: default_clients_rule, default_subnets_rule, clients_rules, subnets_rules Ex: SELECT f.default_clients, f.default_subnets, f.rules_clients, f.rules_subnets FROM firewall_rules f, group_firewall_rules gf, group_users gu WHERE f.firewall_rule_id=gf.firewall_rule_id AND gf.group_id=gu.group_id AND gu.user_id={{user_id}} default_clients and default_subnets MUST BE ACCEPT or DROP (will default to drop if unknown value) clients_rules and subnets_rules must follow Packet Filtering grammar (see below). If NULL, no rules will be used. - Multiple queries In multiple query mode, each query must return its value in first row, first field. The options are: * enable_pf_clients_user_default_rules_query ex: SELECT f.default_clients FROM firewall_rules f, user_firewall_rules uf WHERE f.firewall_rule_id=uf.firewall_rule_id AND uf.user_id={{user_id}} * enable_pf_clients_user_rules_query ex: SELECT f.rules_clients FROM firewall_rules f, user_firewall_rules uf WHERE f.firewall_rule_id=uf.firewall_rule_id AND uf.user_id={{user_id}} * enable_pf_subnets_user_default_rules_query ex: SELECT f.default_subnets FROM firewall_rules f, user_firewall_rules uf WHERE f.firewall_rule_id=uf.firewall_rule_id AND uf.user_id={{user_id}} * enable_pf_subnets_user_rules_query ex: SELECT f.rules_subnets FROM firewall_rules f, user_firewall_rules uf WHERE f.firewall_rule_id=uf.firewall_rule_id AND uf.user_id={{user_id}} AND * enable_pf_clients_group_default_rules_query ex: SELECT f.default_clients FROM firewall_rules f, group_firewall_rules gf, group_users gu WHERE f.firewall_rule_id=gf.firewall_rule_id AND gf.group_id=gu.group_id AND gu.user_id={{user_id}} * enable_pf_clients_group_rules_query ex: SELECT f.rules_clients FROM firewall_rules f, group_firewall_rules gf, group_users gu WHERE f.firewall_rule_id=gf.firewall_rule_id AND gf.group_id=gu.group_id AND gu.user_id={{user_id}} * enable_pf_subnets_group_default_rules_query ex: SELECT f.default_subnets FROM firewall_rules f, group_firewall_rules gf, group_users gu WHERE f.firewall_rule_id=gf.firewall_rule_id AND gf.group_id=gu.group_id AND gu.user_id={{user_id}} * enable_pf_subnets_group_rules_query ex: SELECT f.rules_subnets FROM firewall_rules f, group_firewall_rules gf, group_users gu WHERE f.firewall_rule_id=gf.firewall_rule_id AND gf.group_id=gu.group_id AND gu.user_id={{user_id}} NOTE: At most one row should be returned. In case more than one row is returned, the result will be discarded. That would mean that in case of "group" rules, the user can belong to only 1 group Expandable Variables: +++++++++++++++++++++ Expandable variable should be surrounded by double curly brackets "{{var}}" in the queries, the following are *potentially* available depending on the callback being called: time_now actual unix timestamp (always available) username username sent by client, start to be available when OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY callback is triggered password only available in OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY escaped_username escaped_password same as above, but SQL safe trusted_ip IP the client is connecting with (available with OPENVPN_PLUGIN_CLIENT_CONNECT) trusted_port Port the client is conencting from (available with OPENVPN_PLUGIN_CLIENT_CONNECT) time_unix Timestamo at which client successfully connected (available with OPENVPN_PLUGIN_CLIENT_CONNECT) ifconfig_pool_remote_ip VPN IP given to client (available with OPENVPN_PLUGIN_CLIENT_CONNECT) time_duration Time the connection lasted (available with OPENVPN_PLUGIN_CLIENT_DISCONNECT) bytes_sent Total number of bytes sent to client during VPN session (available with OPENVPN_PLUGIN_CLIENT_DISCONNECT) bytes_received Total number of bytes received from client during VPN session (available with OPENVPN_PLUGIN_CLIENT_DISCONNECT) More detailed info from: man openvpn in section "Environmental Variables" Callback calls: +++++++++++++++ To check in what order the callback will be called, see http://svn.openvpn.net/projects/openvpn/branches/BETA21/openvpn/openvpn-plugin.h Packet Filtering grammar (from openvpn-plugin.h) ------------------------------------------------ * Packet filter file grammar: * * [CLIENTS DROP|ACCEPT] * {+|-}common_name1 * {+|-}common_name2 * . . . * [SUBNETS DROP|ACCEPT] * {+|-}subnet1 * {+|-}subnet2 * . . . * [END] * * Subnet: IP-ADDRESS | IP-ADDRESS/NUM_NETWORK_BITS * * CLIENTS refers to the set of clients (by their common-name) which * this instance is allowed ('+') to connect to, or is excluded ('-') * from connecting to. Note that in the case of client-to-client * connections, such communication must be allowed by the packet filter * configuration files of both clients. * * SUBNETS refers to IP addresses or IP address subnets which this * instance may connect to ('+') or is excluded ('-') from connecting * to. * * DROP or ACCEPT defines default policy when there is no explicit match * for a common-name or subnet. The [END] tag must exist. A special * purpose tag called [KILL] will immediately kill the client instance. * A given client or subnet rule applies to both incoming and outgoing * packets.
About
A flexible OpenVPN plugin to handle user using a MySQL database backend
Resources
License
Stars
Watchers
Forks
Packages 0
No packages published