iFargle / headscale-webui

A simple Headscale web UI for small-scale deployments.
Other
627 stars 57 forks source link

Error - /data not writable #51

Closed PIKACHUIM closed 1 year ago

PIKACHUIM commented 1 year ago

Error - /data not writable /data is not writable. Please ensure your permissions are correct. /data mount should be writable by UID/GID 1000:1000.

iFargle commented 1 year ago

Is your external mount for /data set to 1000:1000? Also worth checking if you have something like SELinux running?

PIKACHUIM commented 1 year ago

Thank you for your reply I used the startup command in SETUP.md to test using the docker When there is no manual mount, the error message above is displayed. I just tried manual mount: -v /xxxxx/data:/data:rw Then display:

Internal Server Error The server encountered an internal error and was unable to complete your request. Either the server is overloaded or there is > an error in the application.

Full command

docker run  -d \
--name xxxx --privileged=true \
--hostname xxxx  \
-v /etc/headscale:/etc/headscale:rw \
-v /xxxx/data:/data:rw \
-p 1078:5000 \
-e HS_SERVER= https://xxxx/server  \
-e KEY=xxxx \
-e DOMAIN_NAME= http://127.0.0.1:5000  \
-e SCRIPT_NAME=/admin ifargle/headscale-webui:latest
iFargle commented 1 year ago

What is the output of docker logs ?

On March 20, 2023 7:08:40 AM UTC, PIKACHUIM @.***> wrote:

Thank you for your reply I used the startup command in SETUP.md to test using the docker When there is no manual mount, the error message above is displayed. I just tried manual mount: -v /xxxxx/data:/data:rw Then display:

Internal Server Error The server encountered an internal error and was unable to complete your request. Either the server is overloaded or there is > an error in the application.

Full command

docker run     -d \
--name xxxx --privileged=true \
--hostname xxxx  \
-v /etc/headscale:/etc/headscale:rw \
-v /xxxx/data:/data:rw \
-p 1078:5000 \
-e HS_ SERVER= https://xxxx/server  \
-e KEY=xxxx \
-e DOMAIN_ NAME= http://127.0.0.1:5000  \
-e SCRIPT_ NAME=/admin ifargle/headscale-webui:latest

-- Reply to this email directly or view it on GitHub: https://github.com/iFargle/headscale-webui/issues/51#issuecomment-1475726438 You are receiving this because you commented.

Message ID: @.> -- Albert J. Copeland @. PGP Fingerprint:  64F6C4EB46C4543A

PIKACHUIM commented 1 year ago
[2023-03-20 07:13:32 +0000] [1] [INFO] Starting gunicorn 20.1.0
[2023-03-20 07:13:32 +0000] [1] [INFO] Listening at: http://0.0.0.0:5000 (1)
[2023-03-20 07:13:32 +0000] [1] [INFO] Using worker: sync
[2023-03-20 07:13:32 +0000] [8] [INFO] Booting worker with pid: 8
[2023-03-20 07:13:33,359] INFO in server: Headscale-WebUI Version:  v0.5.6 / main
[2023-03-20 07:13:33,359] INFO in server: LOG LEVEL SET TO INFO
[2023-03-20 07:13:33,359] INFO in server: DEBUG STATE:  False
[2023-03-20 07:13:37,481] ERROR in helper: /data/key.txt EXIST: FAILED - NO ERROR
[2023-03-20 07:13:37,481] INFO in helper: All startup checks passed.
[2023-03-20 07:13:37,481] INFO in helper: Testing API key validity.
[2023-03-20 07:13:37,563] INFO in helper: Key check passed.
[2023-03-20 07:13:37,563] INFO in headscale: Getting API key information
[2023-03-20 07:13:37,645] ERROR in app: Exception on /overview [GET]
Traceback (most recent call last):
  File "/app/.venv/lib/python3.11/site-packages/requests/models.py", line 971, in json
    return complexjson.loads(self.text, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/json/__init__.py", line 346, in loads
    return _default_decoder.decode(s)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/json/decoder.py", line 337, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/json/decoder.py", line 355, in raw_decode
    raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/app/.venv/lib/python3.11/site-packages/flask/app.py", line 2528, in wsgi_app
    response = self.full_dispatch_request()
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/.venv/lib/python3.11/site-packages/flask/app.py", line 1825, in full_dispatch_request
    rv = self.handle_user_exception(e)
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/.venv/lib/python3.11/site-packages/flask/app.py", line 1823, in full_dispatch_request
    rv = self.dispatch_request()
         ^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/.venv/lib/python3.11/site-packages/flask/app.py", line 1799, in dispatch_request
    return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/server.py", line 131, in decorated
    return view_func(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/server.py", line 143, in overview_page
    pass_checks = str(helper.load_checks())
                      ^^^^^^^^^^^^^^^^^^^^
  File "/app/helper.py", line 285, in load_checks
    if not key_check(): return 'settings_page'
           ^^^^^^^^^^^
  File "/app/helper.py", line 70, in key_check
    headscale.renew_api_key(url, api_key)
  File "/app/headscale.py", line 87, in renew_api_key
    key_info            = get_api_key_info(url, api_key)
                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/headscale.py", line 142, in get_api_key_info
    json_response = response.json()
                    ^^^^^^^^^^^^^^^
  File "/app/.venv/lib/python3.11/site-packages/requests/models.py", line 975, in json
    raise RequestsJSONDecodeError(e.msg, e.doc, e.pos)
requests.exceptions.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
[2023-03-20 07:13:40 +0000] [1] [INFO] Handling signal: winch
iFargle commented 1 year ago

Does your key.txt exist? Can you delete it and re-create? It looks like it isn't recognizing the response Headscale is sending.

PIKACHUIM commented 1 year ago

Update newest log

[2023-03-20 07:35:10,151] INFO in helper: All startup checks passed.
[2023-03-20 07:35:10,151] ERROR in app: Exception on /overview [GET]
Traceback (most recent call last):
  File "/app/.venv/lib/python3.11/site-packages/cryptography/fernet.py", line 116, in _get_unverified_token_data
    data = base64.urlsafe_b64decode(token)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/base64.py", line 134, in urlsafe_b64decode
    return b64decode(s)
           ^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/base64.py", line 88, in b64decode
    return binascii.a2b_base64(s, strict_mode=validate)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
binascii.Error: Incorrect padding

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/app/.venv/lib/python3.11/site-packages/flask/app.py", line 2528, in wsgi_app
    response = self.full_dispatch_request()
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/.venv/lib/python3.11/site-packages/flask/app.py", line 1825, in full_dispatch_request
    rv = self.handle_user_exception(e)
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/.venv/lib/python3.11/site-packages/flask/app.py", line 1823, in full_dispatch_request
    rv = self.dispatch_request()
         ^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/.venv/lib/python3.11/site-packages/flask/app.py", line 1799, in dispatch_request
    return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/server.py", line 131, in decorated
    return view_func(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/server.py", line 143, in overview_page
    pass_checks = str(helper.load_checks())
                      ^^^^^^^^^^^^^^^^^^^^
  File "/app/helper.py", line 285, in load_checks
    if not key_check(): return 'settings_page'
           ^^^^^^^^^^^
  File "/app/helper.py", line 57, in key_check
    api_key    = headscale.get_api_key()
                 ^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/headscale.py", line 50, in get_api_key
    decrypted_key  = fernet.decrypt(enc_api_key).decode()
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/.venv/lib/python3.11/site-packages/cryptography/fernet.py", line 85, in decrypt
    timestamp, data = Fernet._get_unverified_token_data(token)
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/.venv/lib/python3.11/site-packages/cryptography/fernet.py", line 118, in _get_unverified_token_data
    raise InvalidToken
cryptography.fernet.InvalidToken
iFargle commented 1 year ago

Oh wait... How did you generate your KEY= environment variable?

It should be something like KEY="BMqC2kqkFlSYmFN8wW9E2JT1QpGGrdBhsOD8FUUUIwE="

The quotes are important

PIKACHUIM commented 1 year ago

Does your key.txt exist? Can you delete it and re-create? It looks like it isn't recognizing the response Headscale is sending.

Thank you for your patience. I don't know where this key.txt originally was, but I haven't deleted it. I just saw this log and manually tried to create it. The current log information is as follows: "Update new est log"

iFargle commented 1 year ago

Paste your docker-comopose too, just so I have reference :)

PIKACHUIM commented 1 year ago

Oh wait... How did you generate your KEY= environment variable? It should be something like KEY="BMqC2kqkFlSYmFN8wW9E2JT1QpGGrdBhsOD8FUUUIwE=" The quotes are important

Thank you! I started it directly using the docker command:

docker run -d \
    --name pika-scale --privileged=true \
    --hostname pika-scale-<my domain> \
    -v /etc/headscale:/etc/headscale:rw \
    -v /<path>/data:/data:rw \
    -p 1078:5000 \
    -e HS_SERVER=https://<my domain>/server \
    -e KEY=grlbUknV6LX+rly7VpusJYtHUXzOQc4IPHwLY2FP5Bc= \
    -e DOMAIN_NAME=http://127.0.0.1:5000 \
    -e SCRIPT_NAME=/admin ifargle/headscale-webui:latest

open url: http://xxxxx:1078/

PIKACHUIM commented 1 year ago

In addition, I used the nginx reverse proxy for my headscale service. So I modified HS_ SERVER, let it point to an https address with a path. I wonder if this will affect

iFargle commented 1 year ago

-e KEY="grlbUknV6LX+rly7VpusJYtHUXzOQc4IPHwLY2FP5Bc=" \ Try this

PIKACHUIM commented 1 year ago

Still not work. I'm trying docker-compose.yml

iFargle commented 1 year ago

In addition, I used the nginx reverse proxy for my headscale service. So I modified HS_ SERVER, let it point to an https address with a path. I wonder if this will affect

It shouldn't. Mine goes through traefik, so long as your API is https://domain/server/ (ie, https://domain/server/api/v1/apikey)

iFargle commented 1 year ago

Oh, the SCRIPT_NAME is the bath path (per gunicorn) Try going to http://xxxxxx:1078/admin/ (or remove SCRIPT_NAME environment variable)

PIKACHUIM commented 1 year ago

Oh, the SCRIPT_NAME is the bath path (per gunicorn) Try going to http://xxxxxx:1078/admin/ (or remove SCRIPT_NAME environment variable)

The same, I have already used http://xxxxxx:1078/admin/

What is the HS_SERVER should be? My Server not open all ports. https://domain/server/ is just proxy the listen_addr: 0.0.0.0:8080

PIKACHUIM commented 1 year ago

_get_unverified_token_data, fernet.py:121

        if not data or data[0] != 0x80:
            raise InvalidToken

Key is not right, I don't know how to create right key. I create key from openssl rand -base64 32

iFargle commented 1 year ago

Can you paste the full logs there?

PIKACHUIM commented 1 year ago
-------------------------------------------------------------------------------
pydev debugger: CRITICAL WARNING: This version of python seems to be incorrectly compiled (internal generated filenames are not absolute)
pydev debugger: The debugger may still function, but it will work slower and may miss breakpoints.
pydev debugger: Related bug: http://bugs.python.org/issue1666807
-------------------------------------------------------------------------------
Connected to pydev debugger (build 222.4459.20)
pydev debugger: Unable to find real location for: <frozen codecs>
pydev debugger: Unable to find real location for: <frozen importlib._bootstrap>
pydev debugger: Unable to find real location for: <frozen importlib._bootstrap_external>
pydev debugger: Unable to find real location for: <frozen zipimport>
pydev debugger: Unable to find real location for: <string>
pydev debugger: Unable to find real location for: <frozen _collections_abc>
pydev debugger: Unable to find real location for: <frozen os>
pydev debugger: Unable to find real location for: <frozen abc>
pydev debugger: Unable to find real location for: <frozen io>
pydev debugger: Unable to find real location for: <frozen ntpath>
pydev debugger: Unable to find real location for: <frozen importlib.util>
pydev debugger: Unable to find real location for: <werkzeug routing>
pydev debugger: Unable to find real location for: <frozen genericpath>
[2023-03-20 18:26:47,491] INFO in server: LOG LEVEL SET TO DEBUG
[2023-03-20 18:26:47,491] INFO in server: DEBUG STATE:  True
 * Serving Flask app 'server'
 * Debug mode: on
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
 * Running on all addresses (0.0.0.0)
 * Running on http://127.0.0.1:5000
 * Running on http://192.168.255.10:5000
Press CTRL+C to quit
 * Restarting with stat
-------------------------------------------------------------------------------
pydev debugger: CRITICAL WARNING: This version of python seems to be incorrectly compiled (internal generated filenames are not absolute)
pydev debugger: The debugger may still function, but it will work slower and may miss breakpoints.
pydev debugger: Related bug: http://bugs.python.org/issue1666807
-------------------------------------------------------------------------------
pydev debugger: Unable to find real location for: <frozen importlib._bootstrap>
pydev debugger: Unable to find real location for: <frozen runpy>
pydev debugger: Unable to find real location for: <frozen importlib.util>
pydev debugger: Unable to find real location for: <frozen importlib._bootstrap_external>
pydev debugger: Unable to find real location for: <frozen zipimport>
pydev debugger: Unable to find real location for: <string>
pydev debugger: Unable to find real location for: <frozen _collections_abc>
pydev debugger: Unable to find real location for: <frozen os>
pydev debugger: Unable to find real location for: <frozen abc>
pydev debugger: Unable to find real location for: <frozen io>
pydev debugger: Unable to find real location for: <frozen ntpath>
pydev debugger: Unable to find real location for: <werkzeug routing>
pydev debugger: Unable to find real location for: <frozen genericpath>
[2023-03-20 18:26:49,094] INFO in server: LOG LEVEL SET TO DEBUG
[2023-03-20 18:26:49,095] INFO in server: DEBUG STATE:  True
 * Debugger is active!
 * Debugger PIN: 895-675-041
pydev debugger: Unable to find real location for: <frozen codecs>
[2023-03-20 18:26:49,398] INFO in helper: All startup checks passed.
127.0.0.1 - - [20/Mar/2023 18:26:49] "GET / HTTP/1.1" 500 -
Traceback (most recent call last):
  File "D:\PythonEnv\VPNScale\Lib\site-packages\flask\app.py", line 2551, in __call__
    return self.wsgi_app(environ, start_response)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "D:\PythonEnv\VPNScale\Lib\site-packages\werkzeug\middleware\proxy_fix.py", line 187, in __call__
    return self.app(environ, start_response)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "D:\PythonEnv\VPNScale\Lib\site-packages\flask\app.py", line 2531, in wsgi_app
    response = self.handle_exception(e)
               ^^^^^^^^^^^^^^^^^^^^^^^^
  File "D:\PythonEnv\VPNScale\Lib\site-packages\flask\app.py", line 2528, in wsgi_app
    response = self.full_dispatch_request()
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "D:\PythonEnv\VPNScale\Lib\site-packages\flask\app.py", line 1825, in full_dispatch_request
    rv = self.handle_user_exception(e)
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "D:\PythonEnv\VPNScale\Lib\site-packages\flask\app.py", line 1823, in full_dispatch_request
    rv = self.dispatch_request()
         ^^^^^^^^^^^^^^^^^^^^^^^
  File "D:\PythonEnv\VPNScale\Lib\site-packages\flask\app.py", line 1799, in dispatch_request
    return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "D:\MyProject\OpenProjects\headscale-webui\server.py", line 133, in decorated
    return view_func(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "D:\MyProject\OpenProjects\headscale-webui\server.py", line 145, in overview_page
    pass_checks = str(helper.load_checks())
                      ^^^^^^^^^^^^^^^^^^^^^
  File "D:\MyProject\OpenProjects\headscale-webui\helper.py", line 286, in load_checks
    if not key_check(): return 'settings_page'
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "D:\MyProject\OpenProjects\headscale-webui\helper.py", line 58, in key_check
    api_key    = headscale.get_api_key()
                 ^^^^^^^^^^^^^^^^^^^^^^^
  File "D:\MyProject\OpenProjects\headscale-webui\headscale.py", line 49, in get_api_key
    decrypted_key  = fernet.decrypt(enc_api_key).decode()
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "D:\PythonEnv\VPNScale\Lib\site-packages\cryptography\fernet.py", line 85, in decrypt
    timestamp, data = Fernet._get_unverified_token_data(token)
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "D:\PythonEnv\VPNScale\Lib\site-packages\cryptography\fernet.py", line 121, in _get_unverified_token_data
    raise InvalidToken
cryptography.fernet.InvalidToken
pydev debugger: Unable to find real location for: <frozen posixpath>
127.0.0.1 - - [20/Mar/2023 18:26:49] "GET /?__debugger__=yes&cmd=resource&f=debugger.js HTTP/1.1" 304 -
127.0.0.1 - - [20/Mar/2023 18:26:49] "GET /?__debugger__=yes&cmd=resource&f=style.css HTTP/1.1" 304 -
127.0.0.1 - - [20/Mar/2023 18:26:49] "GET /?__debugger__=yes&cmd=resource&f=console.png HTTP/1.1" 304 -
127.0.0.1 - - [20/Mar/2023 18:26:49] "GET /?__debugger__=yes&cmd=resource&f=console.png HTTP/1.1" 304 -
iFargle commented 1 year ago

If you cat /data/key.txt what's in there? I've never seen this error before :(

PIKACHUIM commented 1 year ago

I run server.py on local pc, it's in /data/key.txt, c6m6TI8gUkUYK0OV01gLzYm/UEvMBUD47aH+lMFZVxE=

PIKACHUIM commented 1 year ago

I create a key start with 0x80: gCh8iHRpmpFY60Zy3RwGiI1uFCXSklA0dWEztmd9c/g=, it work, but:

-------------------------------------------------------------------------------
pydev debugger: CRITICAL WARNING: This version of python seems to be incorrectly compiled (internal generated filenames are not absolute)
pydev debugger: The debugger may still function, but it will work slower and may miss breakpoints.
pydev debugger: Related bug: http://bugs.python.org/issue1666807
-------------------------------------------------------------------------------
Connected to pydev debugger (build 222.4459.20)
pydev debugger: Unable to find real location for: <frozen codecs>
pydev debugger: Unable to find real location for: <frozen importlib._bootstrap>
pydev debugger: Unable to find real location for: <frozen importlib._bootstrap_external>
pydev debugger: Unable to find real location for: <frozen zipimport>
pydev debugger: Unable to find real location for: <string>
pydev debugger: Unable to find real location for: <frozen _collections_abc>
pydev debugger: Unable to find real location for: <frozen os>
pydev debugger: Unable to find real location for: <frozen abc>
pydev debugger: Unable to find real location for: <frozen io>
pydev debugger: Unable to find real location for: <frozen ntpath>
pydev debugger: Unable to find real location for: <frozen importlib.util>
pydev debugger: Unable to find real location for: <werkzeug routing>
pydev debugger: Unable to find real location for: <frozen genericpath>
[2023-03-20 18:27:30,764] INFO in server: LOG LEVEL SET TO DEBUG
[2023-03-20 18:27:30,765] INFO in server: DEBUG STATE:  True
 * Serving Flask app 'server'
 * Debug mode: on
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
 * Running on all addresses (0.0.0.0)
 * Running on http://127.0.0.1:5000
 * Running on http://192.168.255.10:5000
Press CTRL+C to quit
 * Restarting with stat
-------------------------------------------------------------------------------
pydev debugger: CRITICAL WARNING: This version of python seems to be incorrectly compiled (internal generated filenames are not absolute)
pydev debugger: The debugger may still function, but it will work slower and may miss breakpoints.
pydev debugger: Related bug: http://bugs.python.org/issue1666807
-------------------------------------------------------------------------------
pydev debugger: Unable to find real location for: <frozen importlib._bootstrap>
pydev debugger: Unable to find real location for: <frozen runpy>
pydev debugger: Unable to find real location for: <frozen importlib.util>
pydev debugger: Unable to find real location for: <frozen importlib._bootstrap_external>
iFargle commented 1 year ago

Oh wait wait wait...

Is that your "KEY" environment variable or what's in key.txt? If that's what's in key.txt, that isn't correct.

Delete key.txt and run touch /path/to/data/key.txt && chown -R 1000:1000 /path/to/data and try again

PIKACHUIM commented 1 year ago

I'm sure key.txt is ok to be read. See:

I create a key start with 0x80: gCh8iHRpmpFY60Zy3RwGiI1uFCXSklA0dWEztmd9c/g=, it work, but:...

iFargle commented 1 year ago

So, the program takes the environment variable KEY and uses that to encrypt the data that goes into key.txt Key.txt contains the encrypted Headscale API key, that's encrypted with the "KEY" variable

iFargle commented 1 year ago

I'm sure key.txt is ok to be read. See:

I create a key start with 0x80: gCh8iHRpmpFY60Zy3RwGiI1uFCXSklA0dWEztmd9c/g=, it work, but:...

What is the contents of /data/key.txt? Did you edit the file manually or was it automatically created?

PIKACHUIM commented 1 year ago

Edit the file manually. If not edit /data/key.txt, it show errors.

So, the program takes the environment variable KEY and uses that to encrypt the data that goes into key.txt Key.txt contains the encrypted Headscale API key, that's encrypted with the "KEY" variable

So how should I handle the/data/key.txt and KEY environment variables?

iFargle commented 1 year ago

KEY environment variable is specific It must be KEY="YourKeybetweenQuotes" generated by openssl rand -base64 32, ie KEY="sQRXt0d2z6zvxJt36IpP8WID9xbKiQSaAwlA0bQ4x1Q="

key.txt should either be nonexistent or should be entirely blank before first run and owned by 1000:1000: -rw-r--r--. 1 1000 1000 164 Feb 26 12:39 /path/to/data/key.txt To make sure this is the case, run the following: touch /path/to/data/key.txt && chown -R 1000:1000 /path/to/data/

/path/to/data should be owned by 1000:1000 and rw:

# ls -lahn /path/to/data/
total 12K
drwxr-xr-x. 2 1000 1000 4.0K Mar 20 11:02 .
-rw-r--r--. 1 1000 1000  164 Feb 26 12:39 key.txt

Then, you create your Headscale API key. That key will be input on the settings page on the program.

So three parts:

  1. Your encryption key (the KEY environment variable)
  2. The key.txt file, which the program will generate. The only manual intervention here should be making sure its permissions are correct above.
  3. Your headscale API key itself, which will be stored in key.txt, encrypted by the KEY environment variable.

Hope this helps!

PIKACHUIM commented 1 year ago

Thank you! So, HS_SERVER is the URL for your Headscale control server. It should be which url? I use https://IP:Port/server/, this proxy the Headscale listen_addr 0.0.0.0:8080

iFargle commented 1 year ago

Doesn't matter what, so long as your container can reach it. Some people just use <headscale's container_name>:8080 -- I use my headscale's externally available address.

So if you can access your headscale server externally from http://IP:Port/server, then that should work!

PIKACHUIM commented 1 year ago

Thank you, However it do NOT work:

[2023-03-20 11:20:06 +0000] [1] [INFO] Starting gunicorn 20.1.0
[2023-03-20 11:20:06 +0000] [1] [INFO] Listening at: http://0.0.0.0:5000 (1)
[2023-03-20 11:20:06 +0000] [1] [INFO] Using worker: sync
[2023-03-20 11:20:06 +0000] [8] [INFO] Booting worker with pid: 8
[2023-03-20 11:20:07,413] INFO in server: Headscale-WebUI Version:  v0.5.6 / main
[2023-03-20 11:20:07,413] INFO in server: LOG LEVEL SET TO INFO
[2023-03-20 11:20:07,413] INFO in server: DEBUG STATE:  False
[2023-03-20 11:20:08,254] ERROR in helper: /data/key.txt EXIST: FAILED - NO ERROR
[2023-03-20 11:20:08,254] INFO in helper: All startup checks passed.
[2023-03-20 11:20:08,254] INFO in helper: Testing API key validity.
[2023-03-20 11:20:08,332] INFO in helper: Key check passed.
[2023-03-20 11:20:08,333] INFO in headscale: Getting API key information
[2023-03-20 11:20:08,408] ERROR in app: Exception on / [GET]
Traceback (most recent call last):
  File "/app/.venv/lib/python3.11/site-packages/requests/models.py", line 971, in json
    return complexjson.loads(self.text, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/json/__init__.py", line 346, in loads
    return _default_decoder.decode(s)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/json/decoder.py", line 337, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/json/decoder.py", line 355, in raw_decode
    raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/app/.venv/lib/python3.11/site-packages/flask/app.py", line 2528, in wsgi_app
    response = self.full_dispatch_request()
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/.venv/lib/python3.11/site-packages/flask/app.py", line 1825, in full_dispatch_request
    rv = self.handle_user_exception(e)
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/.venv/lib/python3.11/site-packages/flask/app.py", line 1823, in full_dispatch_request
    rv = self.dispatch_request()
         ^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/.venv/lib/python3.11/site-packages/flask/app.py", line 1799, in dispatch_request
    return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/server.py", line 131, in decorated
    return view_func(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/server.py", line 143, in overview_page
    pass_checks = str(helper.load_checks())
                      ^^^^^^^^^^^^^^^^^^^^
  File "/app/helper.py", line 285, in load_checks
    if not key_check(): return 'settings_page'
           ^^^^^^^^^^^
  File "/app/helper.py", line 70, in key_check
    headscale.renew_api_key(url, api_key)
  File "/app/headscale.py", line 87, in renew_api_key
    key_info            = get_api_key_info(url, api_key)
                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/headscale.py", line 142, in get_api_key_info
    json_response = response.json()
                    ^^^^^^^^^^^^^^^
  File "/app/.venv/lib/python3.11/site-packages/requests/models.py", line 975, in json
    raise RequestsJSONDecodeError(e.msg, e.doc, e.pos)
requests.exceptions.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
iFargle commented 1 year ago

So it's failing at getting the API key information from headscale... Run the following:

curl -X GET     <Yourheadscaleserver>/api/v1/apikey \
-H "Accept:  application/json" \
-H "Authorization:  Bearer <YourHeadscaleAPIKey>"

and paste the output here Failing here: https://github.com/iFargle/headscale-webui/blob/17b4a44d9f096d18a31061ae7fcf9adf28349eed/headscale.py#L133-L151

PIKACHUIM commented 1 year ago

Nothing output.

iFargle commented 1 year ago

That's the problem. You should have a rather lengthy JSON output of your API keys

PIKACHUIM commented 1 year ago

Thank you. I found my headscale not right, trying to find reason.

iFargle commented 1 year ago

It should be the same endpoint as the one you're using to register machines on. If you go to http(s)://YourHeadscaleServer/swagger, do you get the API reference docs?

PIKACHUIM commented 1 year ago

It should be the same endpoint as the one you're using to register machines on. If you go to http(s)://YourHeadscaleServer/swagger, do you get the API reference docs?

Nothing output. But nodes are still connected. It must be problem problem.

iFargle commented 1 year ago

Well, glad I could help narrow it down! Let me know if you need any more assistance, I'd be glad to help

If both are hosted on the same Docker host, it might be easiest to put HS_SERVER to something like http://YourHeadscaleServer-container_name:8080

For example, if your headscale server's container_name is headscale: - HS_SERVER=http://headscale:8080/ should work

PIKACHUIM commented 1 year ago

I have found the reason. Thank you for your guidance. Reason: The headscale and headscale UI cannot use the same server name My initial plan:

Headscale Service -->Listens to port 1070 -->Nginx Proxy https://IP:Port/server Headscale WebUI -->Listens to Port 1078 -->Nginx Proxy https://IP:Port/admin And then let HS_SERVER= https://Domain:Port/server

However, this does not work, which may result in the Headscale service not working properly (the reason was not found, but it may be caused by the Headscale service not being able to use the path) This is how it works:

Headscale Service -->Listens to port 1070 -->Nginx Proxy https://Name1:Port Headscale WebUI -->Listens to Port 1078 -->Nginx Proxy https://Name2:Port And then let HS_SERVER= https://Name1:Port

PIKACHUIM commented 1 year ago

Thank you again for your patient guidance! Thank you very much!