OpenVPN custom ports and bridge with SELinux enabled

Filed in Linux | Networking Leave a comment

By default, SELinux policy on RHEL/CentOS only allow OpenVPN to work only on port 1194, and also without ability to execute brctl for setup bridge (even you configured script-security 2 in config)

You need to create SELinux plugins module to enable OpenVPN to execute brctl from external script and also able to connect any ports, but not listen (read bottom of this article, there is the way to enable allow listen to specific ports that not already defined by other SELinux policy).

here is how …

First, install required package

  • checkpolicy
  • policycoreutils
  • policycoreutils-python

create folder for store plugins such as /etc/selinux/local, cd to that folder

create openvpn-local.te files

module openvpn-local 1.0;

require {
        type openvpn_t;
        type port_t;
        type brctl_exec_t;
        class file { read getattr open execute execute_no_trans };
        class tcp_socket { name_connect };

#============= openvpn_t ==============
allow openvpn_t brctl_exec_t:file { read getattr open execute execute_no_trans };
allow openvpn_t port_t:tcp_socket { name_connect };

then compile module with

# checkmodule -M -m openvpn-local.te -o openvpn-local.mod

Then package selinux module with

# semodule_package -o openvpn-local.pp -m openvpn-local.mod

You can also download my prepackaged plugin here.

Now module is compiled, you can install by run

# semodule -i openvpn-local.pp

From now on, you should able to connect to OpenVPN and can execute brctl for interface setup scripts from OpenVPN.
Actually we can also enable OpenVPN script to execute any binary, but it too risky and not recommended (I will not talk into details here, it can complete by adjust above policy a bit).

But if you want OpenVPN to be able to listen to other port other than 1194. Create policy for listen to any ports is too risk, the safe way is to edit SELinux policy openvpn_t port lists. This archived by using this command to list ports allow by current openvpn SELinux policy.

# semanage port -l | grep openvpn_port_t
openvpn_port_t                 tcp      1194
openvpn_port_t                 udp      1194

This show only tcp/udp 1194. Now add the ports you want, but SELinux only allow port not defined by others type (see output of ‘semanage port -l’ to check which ports already defined).

This command add TCP port 11940 to openvpn_port_t to SELinux Policy

# semanage port -a -t openvpn_port_t -p tcp 11940

Your OpenVPN now should able listen on TCP port 11940.

I usually use this to test captive-portal remotely using VM bridged to OpenVPN interface that bridged to hotspot network on remote side.
This is example of my openvpn configuration that bridge to vlan10 bridge. (I did not include any encryption here, just for testing).


port 11940
proto tcp-server
dev-type tap
dev vpn.hotspot
script-security 2
up /etc/openvpn/hotspot.up

hotspot.up (remember to chmod +x)


/sbin/ip link set dev vpn.hotspot up
/usr/sbin/brctl addif vlan10 vpn.hotspot

, , , , , ,