I’ve configured influxdb to use HTTP over a unix domain socket. When the socket is created the permissions are set to 0755 and the socket file is owned by influxdb:influxdb. Because the web server runs as a different user, it is unable to write to the socket. If I chmod 0777
the socket file while influxdb is running it works fine, however each time the process restarts the socket is recreated with the wrong permissions, making it unusable.
OS is Debian 9, version is 1.5.2-1 installed from the debian repo.
deb InfluxDB - Package Repository stretch stable
Here is the relevant configuration:
root@grafana:/tmp# influxd config | grep sock
Merging with configuration at: /etc/influxdb/influxdb.conf
unix-socket-enabled = true
bind-socket = "/var/run/influxdb/influxdb.sock"
From the source code it appeared there was a unix-socket-permissions
setting, but that setting does not show up when influxd config
is run, so I guess it’s not being used. Either way makes no difference.
root@grafana:/tmp# grep unix-socket-permissions /etc/influxdb/influxdb.conf
unix-socket-permissions = 0777
I also changed the default bind-socket
path from /var/run/influxdb.sock
to be located in a subdirectory /var/run/influxdb/influxdb.sock
. This is because on my server root owns /var/run
and there is no global write permissions, thus influxdb could not create the socket file at startup. This seems pretty typical for a linux installation (at least Debian?), so it seems like an odd default setting. Instead, I created the influxdb subdirectory and set ownership to influxdb:influxdb. Maybe the Debian installer should be doing this.
root@grafana:/var/run# stat -c "%U:%G %a %A" /var/run/influxdb
influxdb:influxdb 755 drwxr-xr-x
After influxd is started:
root@grafana:/var/run# stat -c "%U:%G %a %A" /var/run/influxdb/influxdb.sock
influxdb:influxdb 755 srwxr-xr-x
I ran strace and it seems the call to chmod() is skipped. I should occur after the listen() and before the write():
4688 stat("/var/run/influxdb", {st_mode=S_IFDIR|0755, st_size=40, ...}) = 0
4688 unlinkat(AT_FDCWD, "/var/run/influxdb/influxdb.sock", 0) = -1 ENOENT (No such file or directory)
4688 socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0) = 75
4688 setsockopt(75, SOL_SOCKET, SO_BROADCAST, [1], 4) = 0
4688 setsockopt(75, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
4688 bind(75, {sa_family=AF_UNIX, sun_path="/var/run/influxdb/influxdb.sock"}, 34) = 0
4688 listen(75, 128) = 0
4688 epoll_ctl(4, EPOLL_CTL_ADD, 75, {EPOLLIN|EPOLLOUT|EPOLLRDHUP|EPOLLET, {u32=980606448, u64=140283202428400}}) = 0
4688 getsockname(75, {sa_family=AF_UNIX, sun_path="/var/run/influxdb/influxdb.sock"}, [112->34]) = 0
4688 write(2, "2018-04-21T05:46:09.517216Z\tinfo"..., 147) = 147
The write() corresponds to the logger.Info() call after the chmod/chown.
2018-04-21T05:46:09.517216Z info Listening on unix socket {"log_id": "07ageGiG000", "service": "httpd", "addr": "/var/run/influxdb/influxdb.sock"}
I have looked at the code related to this and don’t see any problem, so it’s a little odd. It seems the only way chmod is skipped is if the value passed in to the httpd service is 0, instead of the default which is 0777. Have I encountered a real bug, or is there a configuration error?
httpd/service.go:
...
listener, err := net.Listen("unix", s.bindSocket)
if err != nil {
return err
}
if s.unixSocketPerm != 0 {
if err := os.Chmod(s.bindSocket, os.FileMode(s.unixSocketPerm)); err != nil {
return err
}
}