v2ray-core icon indicating copy to clipboard operation
v2ray-core copied to clipboard

systemd: Replace User=nobody with DynamicUser=yes

Open Frederick888 opened this issue 3 years ago • 16 comments

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

Frederick888 avatar Nov 19 '22 15:11 Frederick888

#428

Before we change it, we must notify packagers of Linux distributions.

AkinoKaede avatar Nov 19 '22 23:11 AkinoKaede

It has been open 120 days with no activity. Remove stale label or comment or this will be closed in 5 days

github-actions[bot] avatar Apr 30 '23 01:04 github-actions[bot]

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.

mydogshitgold avatar May 01 '23 09:05 mydogshitgold

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?

AkinoKaede avatar Jul 29 '23 13:07 AkinoKaede

cc. @IceCodeNew

AkinoKaede avatar Jul 29 '23 14:07 AkinoKaede

just a kindly ping @Frederick888 @AkinoKaede

IceCodeNew avatar Oct 16 '23 12:10 IceCodeNew

It has been open 120 days with no activity. Remove stale label or comment or this will be closed in 5 days

github-actions[bot] avatar Mar 26 '24 01:03 github-actions[bot]

ping @Frederick888 @AkinoKaede

IceCodeNew avatar Mar 26 '24 03:03 IceCodeNew

I would suggest closing this pull request since not many users have expressed concern about this issue. On the other hand, there is a high probability that users may encounter new failures.

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.

IceCodeNew avatar Mar 26 '24 03:03 IceCodeNew

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).

felixonmars avatar Mar 26 '24 04:03 felixonmars

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

IceCodeNew avatar Mar 26 '24 08:03 IceCodeNew

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.

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

YHNdnzj avatar Mar 26 '24 10:03 YHNdnzj

LoadCredential= only passes the selected config into service, so it's more secure than bind mounting the whole config dir. Also, this integrates better with the service manager, allowing for more precise job ordering.

YHNdnzj avatar Mar 26 '24 10:03 YHNdnzj

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.

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:

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.

Here is a example:

read_only: true

VS

> ProtectSystem=strict
> ProtectHome=yes
> PrivateDevices=yes
> PrivateUsers=yes
# PrivateTmp= ?
# RestrictFileSystems= ?

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. And all of those options are scattered throughout a lengthy documentation.

https://www.freedesktop.org/software/systemd/man/latest/systemd.exec.html (189 options with a roughly count) image

VS

https://docs.docker.com/compose/compose-file/05-services/ (84 options with a roughly count) image

IceCodeNew avatar Mar 26 '24 10:03 IceCodeNew

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/

IceCodeNew avatar Mar 26 '24 10:03 IceCodeNew

# PrivateTmp= ?
# RestrictFileSystems= ?

The former is implied by DynamicUser=yes. I don't think there's any need to use latter. The process won't have privilege to mount extra file systems anyway.

If you are interested, you may refer to: https://prefetch.net/blog/index.php/2017/11/27/securing-systemd-services-with-seccomp-profiles/

No need if you check my GitHub profile...

YHNdnzj avatar Mar 26 '24 11:03 YHNdnzj

It has been open 120 days with no activity. Remove stale label or comment or this will be closed in 5 days

github-actions[bot] avatar Jul 25 '24 01:07 github-actions[bot]