gvalkov / tailon

Webapp for looking at and searching through files and streams
Apache License 2.0
312 stars 56 forks source link

Nginx reverse proxy #11

Closed machsix closed 5 years ago

machsix commented 5 years ago

First of all, I would like to appreciate the great work of the author! I want to share my experience of setting nginx reverse proxy for the program. For example, if tailon listens at 127.0.0.1:12323, my goal is to redirect web request to https://www.example.com/log/ to 127.0.0.1:12323 and also create a systemd service to make the program start automatically.

First, I create the following systemd file: /etc/systemd/system/tailon.service and run systemctl daemon-reload, systemctl enable tailon

[Unit]
Description=Tailon
After=syslog.target

[Service]
Type=simple
User=root
Group=root
# tailon must run as root in order to read /var/log/messages
ExecStart=/usr/local/bin/tailon -c /data/wwwroot/tailon.toml /var/log/messages /data/wwwlogs/*.log
Restart=always

[Install]
WantedBy=multi-user.target

Then I create the configuration file /data/wwwroot/tailon.toml like the following

  title = "Tailon file viewer"
  relative-root = "/"
  listen-addr = ["127.0.0.1:12313"]
  allow-download = false
  allow-commands = ["tail", "grep"]

  [commands]

    [commands.tail]
    action = ["tail", "-n", "$lines", "-F", "$path"]

    [commands.grep]
    stdin = "tail"
    action = ["grep", "--text", "--line-buffered", "--color=never", "-e", "$script"]
    default = ".*"

Finally, I configure the nginx files example.conf, which is the hardest part

server {
  listen 80;
  server_name example.com www.example.com;
  location / {
    return   301 https://$server_name$request_uri;
  }
}

server {
  listen 443 ssl http2 proxy_protocol;
  include snippets/letsencrypt.conf;
  include snippets/ssl.conf;
  server_name example.com www.example.com;

  location /log/ {
    sub_filter 'href="/' 'href="/log/';
    sub_filter 'href=\'/' 'href=\'/log/';
    sub_filter 'src="/' 'src="/log/';
    sub_filter 'src=\'/' 'src=\'/log/';
    sub_filter_once off;
    proxy_pass http://127.0.0.1:12313/;
  }

  location /ws/ {
    proxy_pass http://127.0.0.1:12313;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_read_timeout 86400;
  }

The most tricky part is the sub_fiter part in /log/ block, since the frontend of tailon responses html body with css defined at locations like /vfs/** and we need to make it to be /log/vfs/***. Moreover, you need to visit http://www.example.com/log/ (Note the last slash) in order to make it work.

I personally suggest using ngx_http_auth_basic_module module to encrypt the frontend, and also using HTTPS. In addition, you need to recompile nginx with --with-http_sub_module flag to enable the function of sub_filter.

I think the program itself can have the function to define the relative path. But I don't know how hard it is to achieve this. :smile:

gvalkov commented 5 years ago

Hi. Thanks for the report - I've always wondered how to achieve this with nginx. However, there's already an option that makes this easier: -r|--relative-root

tailon -r /tailon/ -b localhost:8084 /var/log/Xorg.0.log
location /tailon/ws {
    proxy_pass http://localhost:8084/tailon/ws;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
}

location /tailon {
    proxy_pass http://localhost:8084;
}
machsix commented 5 years ago

I didn't notice there is a -r option. This is far more elegant! Thank you!

iesl2 commented 5 years ago

@gvalkov, @machsix

It seems that I have an issue with provided configuration...

tailon

/opt/tailon/tailon -b "0.0.0.0:8084" "relative-root=/tailon/" "alias=Catalina,group=Tomcat,/opt/tomcat/logs/catalina.out*" &> "/var/log/tailon.log" &

nginx

server {
        listen 80;
        listen [::]:80;
        server_name domain.com;

        access_log /var/log/nginx/domain.com-access.log main;
        error_log /var/log/nginx/domain.com-error.log;

        location /tailon/ws {
                 proxy_pass http://localhost:8084/tailon/ws;
                 proxy_http_version 1.1;
                 proxy_set_header Upgrade $http_upgrade;
                 proxy_set_header Connection "upgrade";
        }
        location /tailon {
                 proxy_pass http://localhost:8084;
        }
}

cat /var/log/nginx/domain.com-access.log

x.x.x.x - - [19/Mar/2019:07:45:44 +0000] "GET /vfs/dist/3rdparty.js HTTP/1.1" 404 169 "http://domain.com/tailon" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:65.0) Gecko/20100101 Firefox/65.0" "-"

cat /var/log/nginx/domain.com-error.log

2019/03/19 07:45:44 [error] 59233#0: *29 open() "/usr/share/nginx/html/vfs/dist/3rdparty.js" failed (2: No such file or directory), client: x.x.x.x, server: domain.com, request: "GET /vfs/dist/3rdparty.js HTTP/1.1", host: "domain.com", referrer: "http://domain.com/tailon"

cat /var/log/tailon.log

::1 - - [19/Mar/2019:07:45:44 +0000] "GET /tailon HTTP/1.0" 200 6448
Screen Shot 2019-03-19 at 09 52 14

What should I change to make it working with nginx on custom path?

iesl2 commented 5 years ago

Found the issue, it was related to the relative-root option in my start script:

/opt/tailon/tailon -b "0.0.0.0:8084" -r "/tailon/" "alias=Catalina,group=Tomcat,/opt/tomcat/logs/catalina.out" "alias=Other,group=Tomcat,/opt/tomcat/logs/*" "/opt/tomcat/logs/catalina.out" &> "/var/log/tailon.log" &

Now, all working as expected.

emilyzzz commented 5 years ago

I set up for tailon to run on localhost and nginx in front of it. Having tried a few times but still css/js not found. Eventually I found the --relative-root thing from this page, set that on tailon start, and set same on nginx.conf, finally everything works. People can read log on my VM. Thank you so much.

Btw I also set "tailon" to run as a systemd service on Linux centos7, quick script cat /etc/systemd/system/tailon.service

[Unit]
Description=tailon
After=syslog.target

[Service]
WorkingDirectory=/home/jzhang1/payx/ez/tailon/
ExecStart=/usr/bin/bash -c "sudo tailon -r /log/  /var/log/messages -b localhost:9102"
KillMode=process
SyslogIdentifier=tailon

[Install]
WantedBy=multi-user.target

Then run

sudo systemctl daemon-reload
sudo systemctl start tailon

my nginx.conf for reference

        location /log/ws {
             proxy_pass http://localhost:9102/log/ws;
             proxy_http_version 1.1;
             proxy_set_header Upgrade $http_upgrade;
             proxy_set_header Connection "upgrade";
        }
        location /log {
            proxy_pass http://localhost:9102;
        }

Now it runs as daemon in the background, and log goes to /var/log/message.