|
| 1 | +# Linux capability |
| 2 | + |
| 3 | +This article shows configuration and dependent gem installation instruction for enabling Linux capability module on Fluentd core. |
| 4 | + |
| 5 | +## Prerequisites |
| 6 | + |
| 7 | +* gcc and make etc. for building C extension sources |
| 8 | +* libcap-ng package and its depelopment package |
| 9 | + * libcap-ng-dev on Debian GNU/Linux and Ubuntu |
| 10 | + * libcap-ng-devel on CentOS 7/8, Fedora 33, AmazonLinux 2 |
| 11 | +* pkg-config package for linking libcap-ng library |
| 12 | +* Ruby and its development packages |
| 13 | + * ruby-dev on Debian GNU/Linux and Ubuntu |
| 14 | + * ruby-devel on CentOS 7/8, Fedora 33, AmazonLinux 2 |
| 15 | +* `setcap` command |
| 16 | + * libcap2-bin on Debian GNU/Linux and Ubuntu |
| 17 | + * libcap on CentOS 7/8, Fedora 33, AmazonLinux 2 |
| 18 | +* `filecap` command |
| 19 | + * libcap-ng-utils on Debian GNU/Linux and Ubuntu |
| 20 | + * libcap-ng-utils on CentOS 7/8, Fedora 33, AmazonLinux 2 |
| 21 | +* Fluentd v1.12 or later |
| 22 | + |
| 23 | +## Install capability handling gem |
| 24 | + |
| 25 | +Fluentd uses [`capng_c` gem](https://github.com/fluent-plugins-nursery/capng_c) to handle Linux capability. |
| 26 | + |
| 27 | +So, Add this line to your Fluentd' or td-agent's Gemfile: |
| 28 | + |
| 29 | +```ruby |
| 30 | +gem 'capng_c' |
| 31 | +``` |
| 32 | + |
| 33 | +And then execute: |
| 34 | + |
| 35 | + $ bundle |
| 36 | + |
| 37 | +Or install it yourself as for Fluentd: |
| 38 | + |
| 39 | + $ fluent-gem install capng_c |
| 40 | + |
| 41 | +Or install it yourself as for td-agent: |
| 42 | + |
| 43 | + $ td-agent-gem install capng_c |
| 44 | + |
| 45 | +**Note:** capng_c uses `pkg-config` to link libcap-ng library. If you couldn't handle Linux capability with capng_c installation, please confirm `pgk-config` package is installed on your box. |
| 46 | + |
| 47 | +## Capability handling on in_tail |
| 48 | + |
| 49 | +Currently, `in_tail` which is the one of the Fluentd core plugin handles the following Linux capabilities: |
| 50 | + |
| 51 | +* `CAP_DAC_READ_SEARCH` (`:dac_read_search` on `in_tail` code.) |
| 52 | +* `CAP_DAC_OVERRIDE` (`:dac_override` on `in_tail` code.) |
| 53 | + |
| 54 | +Set up `cap_dac_read_search` or `cap_dac_override` to using Ruby executable: |
| 55 | + |
| 56 | +### Using CAP_DAC_READ_SEARCH |
| 57 | + |
| 58 | +```console |
| 59 | +$ sudo setcap cap_dac_read_search=+eip /path/to/bin/ruby |
| 60 | +``` |
| 61 | + |
| 62 | +### Using CAP_DAC_OVERRIDE |
| 63 | + |
| 64 | +```console |
| 65 | +$ sudo setcap cap_dac_override=+eip /path/to/bin/ruby |
| 66 | +``` |
| 67 | + |
| 68 | +**Note:** Under rbenv environment, `which ruby` returns shell script wrapper. If users want to set capability on rbenv-ed Ruby, please use the following command: |
| 69 | + |
| 70 | +```console |
| 71 | +$ sudo setcap YOUR_USING_CAPABILITY=+eip $(rbenv prefix)/bin/ruby |
| 72 | +``` |
| 73 | + |
| 74 | +#### Example setting up capability for rbenv-ed Ruby |
| 75 | + |
| 76 | +```console |
| 77 | +$ sudo setcap cap_dac_override,cap_dac_read_search=+eip $(rbenv prefix)/bin/ruby |
| 78 | +$ filecap $(rbenv prefix)/bin/ruby |
| 79 | +file capabilities |
| 80 | +/home/fluentd/.rbenv/versions/2.6.3/bin/ruby dac_override, dac_read_search |
| 81 | +``` |
| 82 | + |
| 83 | +### Actual Example for Linux capability handling in in_tail |
| 84 | + |
| 85 | +When adding `cap_dac_override` (partial privileges for rw file) and `cap_dac_read_search` (partial privileges for read only), Fluentd/td-agent can handle to read 640 permission files such as `/var/log/syslog`: |
| 86 | + |
| 87 | +```console |
| 88 | +$ ls -lh /var/log/syslog |
| 89 | +-rw-r----- 1 syslog adm 29K Nov 5 14:35 /var/log/syslog |
| 90 | +``` |
| 91 | + |
| 92 | +This file cannot read form ordinal users: |
| 93 | + |
| 94 | +```console |
| 95 | +$ cat /var/log/syslog |
| 96 | +cat: /var/log/syslog: Permission denied |
| 97 | +``` |
| 98 | + |
| 99 | +Attach `cap_dac_read_search` for using Ruby executable binary: |
| 100 | + |
| 101 | +```console |
| 102 | +$ sudo setcap cap_dac_read_search=+eip /path/to/bin/ruby |
| 103 | +$ filecap /path/to/bin/ruby |
| 104 | +file capabilities |
| 105 | +/path/to/bin/ruby dac_read_search |
| 106 | +``` |
| 107 | + |
| 108 | +And prepare the following configuration: |
| 109 | + |
| 110 | +```aconf |
| 111 | +<source> |
| 112 | + @type tail |
| 113 | + path /var/log/syslog |
| 114 | + pos_file /var/run/fluentd/log/syslog_test_with_capability.pos |
| 115 | + tag test |
| 116 | + rotate_wait 5 |
| 117 | + read_from_head true |
| 118 | + refresh_interval 60 |
| 119 | + <parse> |
| 120 | + @type syslog |
| 121 | + </parse> |
| 122 | +</source> |
| 123 | +
|
| 124 | +<match test> |
| 125 | + @type stdout |
| 126 | +</match> |
| 127 | +``` |
| 128 | + |
| 129 | +Make and change ownership directory: |
| 130 | + |
| 131 | +```console |
| 132 | +$ sudo mkdir /var/run/fluentd |
| 133 | +$ sudo chown `whoami` /var/run/fluentd |
| 134 | +``` |
| 135 | + |
| 136 | +Then, run as ordinal user with `cap_dac_read_search` capability attached Ruby: |
| 137 | + |
| 138 | +```console |
| 139 | +$ bundle exec fluentd -c in_tail_camouflage_permission.conf |
| 140 | +2020-11-05 14:47:57 +0900 [info]: parsing config file is succeeded path="example/in_tail.conf" |
| 141 | +2020-11-05 14:47:57 +0900 [info]: gem 'fluentd' version '1.12.0' |
| 142 | +2020-11-05 14:47:57 +0900 [info]: gem 'fluent-plugin-systemd' version '1.0.2' |
| 143 | +2020-11-05 14:47:57 +0900 [info]: using configuration file: <ROOT> |
| 144 | + <source> |
| 145 | + @type tail |
| 146 | + path "/var/log/syslog" |
| 147 | + pos_file "/var/run/fluentd/log/syslog_test_with_capability.pos" |
| 148 | + tag "test" |
| 149 | + rotate_wait 5 |
| 150 | + read_from_head true |
| 151 | + refresh_interval 60 |
| 152 | + <parse> |
| 153 | + @type "syslog" |
| 154 | + unmatched_lines |
| 155 | + </parse> |
| 156 | + </source> |
| 157 | + <match test> |
| 158 | + @type stdout |
| 159 | + </match> |
| 160 | +</ROOT> |
| 161 | +2020-11-05 14:47:57 +0900 [info]: starting fluentd-1.12.0 pid=12109 ruby="2.6.3" |
| 162 | +2020-11-05 14:47:57 +0900 [info]: spawn command to main: cmdline=["/home/fluentd/.rbenv/versions/2.6.3/bin/ruby", "-rbundler/setup", "-Eascii-8bit:ascii-8bit", "/home/fluentd/work/fluentd/vendor/bundle/ruby/2.6.0/bin/fluentd", "-c", "example/in_tail.conf", "--under-supervisor"] |
| 163 | +2020-11-05 14:47:58 +0900 [info]: adding match pattern="test" type="stdout" |
| 164 | +2020-11-05 14:47:58 +0900 [info]: adding source type="tail" |
| 165 | +2020-11-05 14:47:58 +0900 [info]: #0 starting fluentd worker pid=12143 ppid=12109 worker=0 |
| 166 | +2020-11-05 14:47:58 +0900 [info]: #0 following tail of /var/log/syslog |
| 167 | +2020-11-05 09:53:11.000000000 +0900 test: {"host":"fluentd-testing","ident":"anacron","pid":"22613","message":"Job `cron.daily' terminated"} |
| 168 | +2020-11-05 09:53:11.000000000 +0900 test: {"host":"fluentd-testing","ident":"anacron","pid":"22613","message":"Normal exit (1 job run)"} |
| 169 | +2020-11-05 09:55:01.000000000 +0900 test: {"host":"fluentd-testing","ident":"CRON","pid":"24610","message":"(root) CMD (command -v debian-sa1 > /dev/null && debian-sa1 1 1)"} |
| 170 | +``` |
| 171 | + |
| 172 | +Fluentd which is running on ordinal user does not complain as `Permission denied`. |
| 173 | +Users can retrieve root files' contents on non-root process, yay! |
| 174 | + |
| 175 | + |
| 176 | +------------------------------------------------------------------------ |
| 177 | + |
| 178 | +If this article is incorrect or outdated, or omits critical information, please |
| 179 | +[let us know](https://github.com/fluent/fluentd-docs-gitbook/issues?state=open). |
| 180 | +[Fluentd](http://www.fluentd.org/) is an open-source project under |
| 181 | +[Cloud Native Computing Foundation (CNCF)](https://cncf.io/). All components are |
| 182 | +available under the Apache 2 License. |
0 commit comments