This question is related to another question with a great answer and script from @Oliver.
The goal: I want to modify/extend the script provided in this answer to suit my requirements, which are as follows:
-
I have a large number of clients (up to 1000). Each client shall be assigned a subscription class and corresponding maximum data rate based on its CN (common-name). These rate limits shall be applied when the client connects and shall be removed when it disconnects:
bronze
: 1 mbitsilver
: 10 mbitgold
: 100 mbit
-
I would like to adjust each client’s subscription class and corresponding active data rate limit on the fly, while the client is connected to the OpenVPN server. The client should not have to reconnect to the OpenVPN server. Is this possible or do we have to disconnect and reconnect each client to OpenVPN to cause the script to be called again to change the
tc
configuration? -
Instead of modifying the
tc
configuration manually using the shell, how would we update the client subscription class and corresponding active data rate limit on the fly from another computer or application (i.e. via PHP)?
Many thanks
Best Answer
Here is a solution, how to do traffic shaping for data rate limiting of individual clients with
tc
(traffic control) using a script called by OpenVPN.The traffic control settings are handled in a script
tc.sh
with the following features:up
,down
,client-connect
andclient-disconnect
/16
subnets (up to 65534 clients)tc
settings using unique identifiers (hashtables
,handles
,classids
). These identifiers are generated from the last 16 bits of the client's remote vpn IPbronze
,silver
andgold
), to use other classes simply edit the script and modify as needed.Configuration
OpenVPN server configuration
/etc/openvpn/tc/conf
:Replace the DNS servers in the last 2 lines with the correct IP addresses.
Traffic control script
/etc/openvpn/tc/tc.sh
:Make it executable:
Subscription database directory
/etc/openvpn/tc/db/
:This directory contains a file per client named after its CN-name containing the "subscription class" string, configure as follows:
IP database directory
/etc/openvpn/tc/ip/
:This directory will contain the
CN-name <-> IP-address
relation and thetun interface
during run-time, which has to be provided for an external application updating thetc
settings while clients are connected.It will look as follows:
Enable IP forwarding:
Configuring NAT (network address translation):
If you have a static external IP address use
SNAT
:Or if you have a dynamically assigned IP address use
MASQUERADE
(slower):while
<if>
is the name of the external interface (i.e.eth0
)<ip>
is the IP address of the external interfaceScript usage and showing tc configuration
Updating "subscription class" and
tc
settings from external application:While the OpenVPN server is up and the client connected issue the following commands (example to upgrade
client1
to"gold"
subscription):tc
commands to show the settings:Additional information
Notes and possible optimizations:
tc
settings were only tested using a small number of clientstc
settings have to be optimizedifb
interface as explained in this answer.Related documentation for a deeper understanding:
htb
qdisc)add
anddel
operations