-
Notifications
You must be signed in to change notification settings - Fork 4.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
systemd: Replace User=nobody with DynamicUser=yes #2161
base: master
Are you sure you want to change the base?
Conversation
systemd warning: > Special user nobody configured, this is not safe! DynamicUser [1] seems to be the recommended approach now. See also [2]. [1] https://www.freedesktop.org/software/systemd/man/systemd.exec.html#DynamicUser= [2] https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=976858
Before we change it, we must notify packagers of Linux distributions. |
It has been open 120 days with no activity. Remove stale label or comment or this will be closed in 5 days |
Processes running as nobody can ptrace each other, so there is a loss of security if more than one thing is running as that user. Ideally, individual users/DynamicUser would be used in this case. Also, according to LSB, the user "nobody" is used by NFS as a placeholder for "unmapped" users. |
It seems that only Arch-based Linux distros will be affected by this change, and considering that Arch Linux users are generally more professional, I think this change can be merged. @felixonmars, what do you think about this? |
cc. @IceCodeNew |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When was this option introduced into the systemd?
Did you tested it with distros like Debian 10 (August 1st, 2022) to see if there is any problem?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Moreover ProtectSystem=strict and ProtectHome=read-only are implied, thus prohibiting the service to write to arbitrary file system locations. In order to allow the service to write to certain directories, they have to be allow-listed using ReadWritePaths=, but care must be taken so that UID/GID recycling doesn't create security issues involving files created by the service. Use RuntimeDirectory= (see below) in order to assign a writable runtime directory to a service, owned by the dynamic user/group and removed automatically when the unit is terminated. Use StateDirectory=, CacheDirectory= and LogsDirectory= in order to assign a set of writable directories for specific purposes to the service in a way that they are protected from vulnerabilities due to UID reuse (see below).
- Are you sure we do not need to ship the security enforcement along with decent default values of these options?
- I do not expect average users to have ideas of avoiding the problem of UID reuse, not even to be aware of them. It looks like we are introducing another problem to solve an existing one. Does it ever concern you?
just a kindly ping |
It has been open 120 days with no activity. Remove stale label or comment or this will be closed in 5 days |
ping @Frederick888 @AkinoKaede |
I would suggest closing this pull request since not many users have expressed concern about this issue. However, the vulnerability raised by issue #428 is valid. If fixing the problem is not the preferred approach, then it is essential to provide a clear warning to users. In addition to emphasizing that installing V2ray with distributed packages is not secure out of the box, I believe it would be sensible to suggest that users deploy V2ray through Docker containers, which should be much more painless for further security adaptions. |
Sorry for not showing up earlier. Generally, I'm in favor of these types of changes, but I never really figured out how to, for example, associate DynamicUser with a specific path configured 700 (so that it's not readable by everyone). |
That is exactly the case. Limiting file access within Docker containers is generally considered easier and more reliable compared to implementing similar restrictions in systemd. Additionally, Docker allows for the limitation of Linux capabilities and provides other security features. I believe that achieving similar security constraints using a tech stack other than Docker is possible. However, when it comes to systemd, users might have to refer to lengthy documentation where the relevant options are scattered throughout, making it more challenging to configure. By suggesting the use of Docker containers, users can benefit from a more streamlined and centralized approach to security, thereby simplifying the implementation of necessary restrictions. Here is a deployment in real life, I wrote the configuration within about 5-10 mins. I doubt anyone can do the same in systemd while taking time no longer than 1 hour. v2ray:
cap_drop:
- ALL
command: [ "run", "-d", "/usr/local/etc/v2ray/conf.d/" ]
container_name: <REDACTED>
image: <REDACTED>
init: true
network_mode: "service:caddy"
pull_policy: always
read_only: true
restart: always
sysctls:
# mitigate TIME-WAIT Assassination hazards in TCP
- net.ipv4.tcp_rfc1337=1
# SACK is commonly exploited and rarely used
- net.ipv4.tcp_sack=0
- net.ipv4.tcp_dsack=0
- net.ipv4.tcp_fack=0
# SSR could impact TCP's performance on a fixed-speed network (e.g., wired)
- net.ipv4.tcp_slow_start_after_idle=0
ulimits:
nproc: 16384
nofile:
soft: 16384
hard: 16384
memlock:
soft: 8192
hard: 16384
volumes:
- type: bind
source: ./v2ray/conf.d/
target: /usr/local/etc/v2ray/conf.d/
read_only: true |
Sorry, but I think your opinion is highly biased. Just because you're more used to Docker doesn't mean that systemd is substantially harder. I wrote the following service in 3 minutes and I have been using it everyday for 2 years: # /etc/systemd/system/[email protected]
[Unit]
Description=V2Ray instance for %i
Documentation=https://www.v2fly.org
[Service]
DynamicUser=yes
CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_BIND_SERVICE
AmbientCapabilities=CAP_NET_ADMIN CAP_NET_BIND_SERVICE
ConfigurationDirectory=v2ray
ConfigurationDirectoryMode=0700
LoadCredential=config:/etc/v2ray/%i.json
ExecStart=/usr/bin/v2ray run -config "${CREDENTIALS_DIRECTORY}/config" -format jsonv5
Restart=on-failure
RestartPreventExitStatus=23
ProtectSystem=strict
ProtectHome=yes
PrivateDevices=yes
PrivateUsers=yes
ProtectHostname=yes
ProtectClock=yes
ProtectKernelTunables=yes
ProtectKernelModules=yes
ProtectKernelLogs=yes
ProtectControlGroups=yes
LockPersonality=yes
MemoryDenyWriteExecute=yes |
|
That is cool. I am glad you find you way out and willing to share it. For your argument, I do not think we are talking in the same language. The reason I prefer to recommend users to use docker is as following:
Here is a example:
VS
I am confident about how proficient I am in systemd configurations, and I believe there are more options to fill the gap between the docker configurations and systemd configurations, just in terms of restricting file access. The above was what I can recall in a fraction of time. https://www.freedesktop.org/software/systemd/man/latest/systemd.exec.html VS https://docs.docker.com/compose/compose-file/05-services/ |
Not to mention you have missed the seccomp configuration in the systemd configuration, which comes out of the box in the docker engine ;-) If you are interested, you may refer to: https://prefetch.net/blog/index.php/2017/11/27/securing-systemd-services-with-seccomp-profiles/ |
The former is implied by
No need if you check my GitHub profile... |
systemd warning:
DynamicUser [1] seems to be the recommended approach now. See also [2].
[1] https://www.freedesktop.org/software/systemd/man/systemd.exec.html#DynamicUser=
[2] https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=976858