3

I was trying to get the Shadowsocks server running automatically after booting, and I used the rc.local file, but it was not working.

rc.localis now:

/usr/local/bin/ssserver -c /etc/shadowsocks.json -d start
#!/bin/bash
exit 0
  • I added a+x privilege to /etc/rc/d/rc.local.
  • I also fixed the symbolic link /etc/rc.local -> /etc/rc.d/rc.local (default privilege 777) as suggested here.

However, the code in rc.local is still not working when booting. It turned out that rc.local is not running when the system starts. With some help from here, I was able to diagnose the issue further.

Here is the /etc/systemd/system/rc-local.service file (I didn't change anything):

[Unit]
Description=/etc/rc.d/rc.local Compatibility
ConditionFileIsExecutable=/etc/rc.d/rc.local
After=network.target

[Service]
Type=forking
ExecStart=/etc/rc.d/rc.local start
TimeoutSec=0
RemainAfterExit=yes
GuessMainPID=no

-- Is this file okay?

When I do systemctl enable rc-local, I get this error:

The unit files have no installation config (WantedBy, RequiredBy, Also, Alias
settings in the [Install] section, and DefaultInstance for template units).
This means they are not meant to be enabled using systemctl.
Possible reasons for having this kind of units are:
1) A unit may be statically enabled by being symlinked from another unit's 
.wants/ or .requires/ directory.
2) A unit's purpose may be to act as a helper for some other unit which has
a requirement dependency on it.
3) A unit may be started when needed via activation (socket, path, timer,
D-Bus, udev, scripted systemctl call, ...).
4) In case of template units, the unit is meant to be enabled with some
instance name specified.

I am not sure which reason is my situation, since the rc.local file is so simple.

4

You rc.local is corrupt!

/usr/local/bin/ssserver -c /etc/shadowsocks.json -d start
#!/bin/bash
exit 0

Should be

#!/bin/bash
/usr/local/bin/ssserver -c /etc/shadowsocks.json -d start
exit 0

EDIT:

I do not exactly know what is wrong with your rc.local systemd service.

I would, however, create a separate systemd unit for shadowsocks, that way you can start and stop it ... for example, when you want to reload the configuration, and you as well as everybody else who will have to maintain the server knows what service to restart.

A sample shadowsocks systemd unit file:

[Unit]
Description=Shadowsocks proxy server

[Service]
User=www-shadow
Group=www-shadow
Type=simple
ExecStart=/usr/local/bin/ssserver -c /etc/shadowsocks/shadowsocks.json -a shadowsocks -v start
ExecStop=/usr/local/bin/ssserver -c /etc/shadowsocks/shadowsocks.json -a shadowsocks -v stop

[Install]
WantedBy=multi-user.target

Note, here we have a user www-shadow to run the proxy, the user is member of www-shadow group. To keep your /etc tidy, it is better to create a /etc/shadowsocks directory and put the JSON along with any other shadowsocks-related files in there. I got the basics for the systemd unit file above from linode.com, however, they want to run the proxy as root (baaaaaaaaaad) ... given it uses port 8388 by default, I doubt this is necessary. Note that if you do not create a www-shadow user and group for the unit, systemd will happily run the service as root (long story, is "apparently" by design).

I have no experience with shadowsocks (I only ever used squid for proxy and ssh for socks proxies ;-) and no time to look it up, but after a quick look a the unit file, it looks reasonable (apart from the root folly).

Using the rc.local unit file (which is for backwards compatibility) does not make much sense, imho, you miss an ExecStop and you have to remember rc.local is shadowsocks ...

If you want to fix the rc.local unit, it must be 755 (chmod 755 /etc/rc.d/rc.local), nobody wants a world-writable daemon script, this might be another issue with it. Imho, systemd is not always reasonable, but I doubt it would run a world-writable script.

To be on the safe side, could you post the output of ls -l /etc/rc.d/rc.local in your question.

EDIT2:

D'oh (I'm silly, it was there all the time and I did not notice), your unit file is missing an [Install] directive:

[Install]
WantedBy=multi-user.target
  • 1
    I interchanged the first and the second line, and rebooted the machine, but it still does not work. – jackxujh Nov 19 '17 at 10:00
  • 1
    A broken rc.local is not the problem here because systemd doesn't even run rc.local – PiedPiper Nov 20 '17 at 11:05
  • Please add the [Install] directive to your systemd unit file, as the error message suggests ... ;-) That should have systemd run your unit with the multi-user unit. – thecarpy Nov 20 '17 at 11:30
1

Fedora 27 uses systemd which doesn't run /etc/rc.local

There are several solutions or workarounds suggested on AskUbuntu

  • Thanks for the link! I found the /etc/systemd/system/rc-local.service on disk is the default state and I didn't know if there's anything I should change, so I didn't make any changes to it. Then, when I systemctl enable rc-local as the link says, I get The unit files have no installation config (... error. It also suggested 4 problem reasons, but I was not sure what it is saying. – jackxujh Nov 18 '17 at 15:47
  • @jackxujh You should vote up any answers you found useful, and optionally accept the best one – PiedPiper Nov 20 '17 at 11:04
0

To se if /etc/rc.local is "running", you could type something like this in your /etc/rc.local

/bin/date >> /root/test.txt

Reboot and see if there is a date in the file /root/test.txt.

  • Thanks for the heads up! No, it turned out etc/rc.local is not running upon startup. – jackxujh Nov 18 '17 at 15:47
-1

A GUI can make starting and stopping various apps easy; try installing and using gnome-tweak-tool (of course, provided a GUI is applicable).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.