In your case I think you might also stick to standard procedures as most as possible.
Starting from a pristine CentOS 6.10 minimal ISO installation, I would proceed as follows:
First, enable unconfined OpenVPN: CentoOS 6 comes with a stock SELinux policy that by default runs /usr/sbin/openvpn
binary in a restricted mode that basically allows it only networking setups, thus preventing any helper script to be able to do anything useful. However CentOS 6 also provides one simple setting to enable unconfined OpenVPNs. As superuser run:
setsebool -P openvpn_run_unconfined on
hold on a few seconds, as it may take a little while.
You might want to put it back in confined mode once everything works. There a few viable approaches I will come back later to.
Then, to proceed with basic setup, install EPEL repository into your system’s yum:
yum install https://dl.fedoraproject.org/pub/epel/epel-release-latest-6.noarch.rpm
That gives your system’s yum a repository that provides RPMs for openvpn and transmission packaged for CentOS 6.
After that you can do:
yum install openvpn transmission-daemon
Then install the transmission-telegram
bot like you’ve already done. Just make sure to place it in a directory indicated in $PATH
. Taking into consideration CentOS 6's SELinux policy, /usr/local/bin
may be a good choice.
(Please note that I can't really expand more on specifics for the Telegram bot because I don't know anything about it and can't even test it because I don't use Telegram at all.)
Then make an openvpn-transmission-up.sh
script like:
#!/bin/bash
PATH+=":/sbin:/usr/sbin"
service transmission-daemon start
service transmission-daemon status && telegram-bot-start.sh
The telegram-bot-start.sh
is just a hypothetical wrapper to run the actual command that starts the Telegram bot, and is executed only if transmission-daemon started successfully. You might also use the direct command instead of a wrapper script, if the direct command can be made a one-liner to be put after the &&
.
Then also make an openvpn-transmission-down.sh
script like:
#!/bin/bash
PATH+=":/sbin:/usr/sbin"
telegram-bot-stop.sh
service transmission-daemon stop || true
Here too you might use the direct commands for stopping the Telegram bot, instead of the telegram-bot-stop.sh
wrapper, in this case even if they are actually a sequence of commands.
Then make the above two scripts runnable:
chmod +x openvpn-transmission-up.sh openvpn-transmission-down.sh
and place them in /etc/openvpn/scripts
directory (again to comply with CentoOS SELinux policy). Create that directory if you don't have it yet.
Then put your own config for OpenVPN into /etc/openvpn
. Such file can be named however you like but it must have a .conf
suffix.
Make sure you have the following lines in that .conf
file:
script-security 2
route-up scripts/openvpn-transmission-up.sh
route-pre-down scripts/openvpn-transmission-down.sh
If you already have route-up
or route-pre-down
scripts, then just merge your pre-existing scripts with the above ones respectively, but make sure to put them in /etc/openvpn/scripts
.
The above setup makes sure your Transmission and Telegram bot always follow the VPN tunnel's fate.
Finally set openvpn to run at boot:
chkconfig openvpn on
This last setting relies on the setup that comes with the RPM package for OpenVPN, which makes it run only after general networking has successfully started.
Note that I think you don't actually need to configure Transmission, because the default configuration that comes with its RPM package should suffice. However, if you wish to reuse your sed
command to set the IP_ADDRESS, then place that sed
command in the openvpn-transmission-up.sh
script before starting transmission-daemon. Anyways, it is usually better to use $ifconfig_local
instead of $4
.
At this point you should be all set. You may test it through a simple service openvpn
followed by start
or stop
or restart
etc. Or by just rebooting your headless server.
NOTE that if your VPN provider requires authentication through username and password, you will need to put them into a file on two distinct lines. This file should reside in /etc/openvpn
to comply with SELinux policy. Then include auth-user-pass /etc/openvpn/credentials-file
into your openvpn .conf
file. If you don't do so, CentOS will stop during boot waiting for interactive input of credentials, or simply OpenVPN might just refuse to start.
With regard to (re-)hardening the above setup, depending on your preferences you might be happy as it is: the setup thus far takes advantage of allowable settings pre-installed by CentOS, including the one to allow OpenVPN to run with less restrictions, which basically allows the helper scripts to freely execute the binaries available on the system. As loosen as that may sound, it is still more constrained than no SELinux at all, and by leaving things this way, both Transmission and the Telegram bot run with a bit more constraints than their stock (or manual) installation would allow.
If you rather wish to put OpenVPN back in confined operation, it can still be fairly easy by taking advantage of the fact that CentOS 6 actually uses Upstart as its /sbin/init
even though it relies much of the boot operations to the legacy SysVinit-style scripts. However you need some additional steps:
- a (luckily simple) custom SELinux policy to at least allow OpenVPN talk to Upstart so that it asks this latter to start Transmission and the Telegram bot
- a couple of (simple) Upstart jobs for starting Transmission through its legacy scripts and for the Telegram bot
To start, put OpenVPN back in confined mode:
setsebool -P openvpn_run_unconfined off
Now, if you start OpenVPN, the helper scripts won't be able to start Transmission and Telegram bot.
So, the custom SELinux policy:
Make a file named openvpn-talk-upstart.te
exactly as follows:
module openvpn-talk-upstart.mod 1.0;
require {
type openvpn_t;
type init_t;
class unix_stream_socket connectto;
}
allow openvpn_t init_t:unix_stream_socket connectto;
Then run the following commands:
checkmodule -m -M -o openvpn-talk-upstart.mod openvpn-talk-upstart.te
semodule_package -o openvpn-talk-upstart.pp -m openvpn-talk-upstart.mod
semodule -i openvpn-talk-upstart.pp
the last command may take a little while.
Then the Upstart jobs:
Make a /etc/init/transmission-up.conf
file as follows:
task
exec service transmission-daemon start
and a /etc/init/transmission-down.conf
file as follows:
task
exec service transmission-daemon stop
Then you need Upstart jobs for the Telegram bot too.
For consistency with my example I stick to my hypothetical scripts approach, and so the job files, named for instance /etc/init/telegram-bot-up.conf
and /etc/init/telegram-bot-down.conf
, would be like the Transmission ones, only with exec
ed commands turned into (respectively) /usr/local/bin/telegram-bot-start.sh
and /usr/local/bin/telegram-bot-stop.sh
.
Note that here, depending on your confidence with Upstart, you might also put the relevant commands directly in the job files, within script ... end-script
keywords in place of the exec
keyword, or you might even make a fully Upstart-controlled daemon via one single Upstart job file (but not of task
type) if you feel so inclined.
After this, make the OpenVPN helper openvpn-transmission-up.sh
script in /etc/openvpn/scripts
become as follows:
#!/bin/sh
/sbin/start transmission-up && /sbin/start telegram-bot-up
and the openvpn-transmission-down.sh
script:
#!/bin/sh
/sbin/start telegram-bot-down
/sbin/start transmission-down || true
Note the /sbin/start
command used even though it is actually a "down" operation.
Now everything should work, with OpenVPN in its original confined (ie more secure) mode, but both Transmission and the Telegram bot in their standard "free" (ie less secure) mode.
Should you wish to harden these latter two even more, then you'd need to run them in a confined SELinux context, such as the one for OpenVPN, and then do a careful analysis of the /var/log/audit/audit.log
file, in order to adjust the SELinux policy precisely. There are tools that can help you on that, namely the audit2allow
command available from the policycoreutils-python
package.
You can run that command over the audit.log
that comes from a SELinux in permissive mode (see /etc/sysconfig/selinux
file), but that might end up allowing too much. Else you can run it over the audit.log
that comes from a regular enforcing SELinux, doing it step-by-step until you finally get to a working setup. In this latter way you can be sure that you only allow no more than what is exactly needed.
The output from audit2allow -a -m ...
has to be fed to checkmodule -m -M -o ...
, then this latter's output to semodule_package -o ... -m ...
, and finally a semodule -i
of the file generated by semodule_package
. This iteration at each step of the analysis.
It can be a very long task, and even when you get to a working setup, it could be so only initially: at some point you might get into unexpected "permission denied" problems later on, e.g. the first time your Transmission, or Telegram Bot, tries to access something it hadn't tried before.
--up
parameter when initializing the vpn in openvpn-custom? – Marcy May 03 '19 at 09:41chkconfig
on it returnsservice openvpn-custom does not support chkconfig
. – Marcy May 03 '19 at 09:54service ... start
andstop
(can you be more precise on the purpose here ?) 2: normally you can check the status withservice openvpn-custom status
but otherwise you could do better and check connectivity on your vpn network for instance in your bash ping an ip on the vpn end see the script bellow 3: if every time you use the vpn you will need your applications, you can put everything in a signe script openvpn-custom --up is useful tho because it's launched only when the connection succeed – intika May 03 '19 at 11:28# Required-Start: $network
and# Required-Stop: $network
in your service to make it depend on something else – intika May 03 '19 at 11:39/full-path-to/your/vpn-script/vpn.sh
in the file; why not just the contents of the script directly? Is there a preference? 2) I know how to check the status, but your solutions have thestatus
command empty, so it returns nothing. 3) My thoughts exactly, yes: if I always want to use these together, might as well avoid the loops or checking for statuses you mention, and just use--up
instead, right? – Marcy May 03 '19 at 13:31