x-ui.service.debian 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. [Unit]
  2. Description=x-ui Service
  3. After=network.target
  4. Wants=network.target
  5. StartLimitIntervalSec=180
  6. StartLimitBurst=10
  7. [Service]
  8. EnvironmentFile=-/etc/default/x-ui
  9. Environment="XRAY_VMESS_AEAD_FORCED=false"
  10. Type=simple
  11. WorkingDirectory=/usr/local/x-ui/
  12. ExecStart=/usr/local/x-ui/x-ui
  13. ExecReload=/bin/kill -USR1 $MAINPID
  14. Restart=on-failure
  15. RestartSec=5s
  16. # The panel intentionally stays root: it supervises the Xray child processes,
  17. # edits netfilter state and reads TLS private keys. These settings only bound
  18. # what a panel-level flaw can reach.
  19. #
  20. # PrivateTmp=yes is deliberately absent: the web updater writes its script into
  21. # /tmp and hands the absolute path to a "systemd-run" transient unit, which
  22. # does not share this service's private /tmp (the download would vanish).
  23. NoNewPrivileges=yes
  24. ProtectSystem=full
  25. # Default stores: DB/update status/node-token in XUI_DB_FOLDER (/etc/x-ui),
  26. # xray binary/config/geo in XUI_BIN_FOLDER under /usr/local/x-ui, logs in
  27. # XUI_LOG_FOLDER (/var/log/x-ui). These are the plain-install defaults and the
  28. # floor, not the whole list: install.sh and update.sh regenerate a drop-in
  29. # (x-ui.service.d/10-xui-sandbox.conf) with the folders resolved from the XUI_*
  30. # variables, so a relocated XUI_DB_FOLDER or XUI_LOG_FOLDER stays writable and
  31. # the list survives an update instead of being reset to these defaults. Changing
  32. # one of those variables in the env file is not enough by itself: the drop-in has
  33. # to be refreshed as well, i.e. install or update the panel again.
  34. # Add local extras in your own drop-in (e.g. 20-local.conf).
  35. # The leading '-' keeps the unit startable if a path does not exist yet.
  36. # What ProtectSystem=full covers, precisely: /usr, /boot, /efi and /etc become
  37. # read-only, everything else stays writable. So this list matters for stores
  38. # under those trees -- the default main folder under /usr/local is one.
  39. #
  40. # The in-panel updater is expected to leave this sandbox: it runs update.sh
  41. # through a transient systemd-run unit, which does not inherit these settings.
  42. # Its plain-child fallback (taken when systemd-run is unavailable) cannot work
  43. # here -- update.sh stages the release archive beside the main folder, replaces
  44. # /usr/bin/x-ui and calls the package manager -- so it stops with one clear
  45. # message instead of failing halfway, and the sandbox deliberately does not
  46. # grant /usr or /etc to accommodate it.
  47. # ReadWritePaths= requires systemd >= 231; ReadWriteDirectories= is the deprecated
  48. # alias for older systemd, needed so ProtectSystem=full keeps /etc/x-ui writable.
  49. ReadWritePaths=-/etc/x-ui -/usr/local/x-ui -/var/log/x-ui
  50. ReadWriteDirectories=-/etc/x-ui -/usr/local/x-ui -/var/log/x-ui
  51. # A kernel-TUN WireGuard outbound zeroes net.ipv{4,6}.conf.*.rp_filter as Xray starts
  52. # (#6796). Reopen only /proc/sys/net: kernel.* (core_pattern among them) stays read-only.
  53. # No ReadWriteDirectories alias needed: ProtectKernelTunables itself requires systemd 232.
  54. ReadWritePaths=-/proc/sys/net
  55. ProtectKernelTunables=yes
  56. ProtectKernelModules=yes
  57. ProtectKernelLogs=yes
  58. ProtectClock=yes
  59. ProtectHostname=yes
  60. # read-only rather than yes: installs keep TLS certs under /root/cert, and the
  61. # panel must still be able to read them.
  62. ProtectHome=read-only
  63. LockPersonality=yes
  64. RestrictRealtime=yes
  65. RestrictSUIDSGID=yes
  66. RestrictNamespaces=yes
  67. UMask=0077
  68. # AF_NETLINK for interface/route lookups and the ip(8) child used by the
  69. # AmneziaWG IPv6-alias feature.
  70. RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX AF_NETLINK
  71. # NET_ADMIN for ip(8)/tproxy, NET_BIND_SERVICE for ports below 1024, NET_RAW
  72. # for raw sockets and SO_BINDTODEVICE.
  73. #
  74. # DAC_OVERRIDE has to stay. The panel runs as root, but a bounding set is
  75. # subtracted from root's own privileges too: without it root can only read a
  76. # file when the owner/group/other bits let uid 0 through, and any TLS private
  77. # key belonging to another account becomes unreadable -- a certificate issued to
  78. # Caddy, an acme.sh home, any 0600 file that root does not own. TLS then fails
  79. # quietly: the panel listener catches the tls.LoadX509KeyPair error, logs it and
  80. # keeps serving plain HTTP, and every Xray inbound using that key stops. Those
  81. # reads worked before the sandbox because the panel is root.
  82. # DAC_READ_SEARCH is deliberately absent: directory search is already covered by
  83. # DAC_OVERRIDE, so it would only widen the set without adding anything.
  84. CapabilityBoundingSet=CAP_DAC_OVERRIDE CAP_NET_ADMIN CAP_NET_BIND_SERVICE CAP_NET_RAW
  85. SystemCallArchitectures=native
  86. # No seccomp whitelist here on purpose. @system-service needs systemd >= 239
  87. # (other @-named groups exist since 231), and older systemd does not ignore an
  88. # unknown group name gracefully: on
  89. # <231 the name fails to resolve and the filter stays the built-in whitelist of
  90. # execve/exit/exit_group/rt_sigreturn/sigreturn, on 231..238 it degrades to
  91. # @default -- either way the panel then gets EPERM on read/openat/mmap/clone and
  92. # cannot start. install.sh and update.sh add SystemCallFilter=@system-service and
  93. # SystemCallErrorNumber=EPERM to the generated drop-in, but only when
  94. # "systemctl --version" reports 239 or newer.
  95. [Install]
  96. WantedBy=multi-user.target