How to set up TLS for 1Password Connect?

XIIIXIII
Community Member
edited April 4 in Secrets Automation

The documentation on setting up TLS for 1Password Connect is too brief for me...

  • Where do I need to set OP_HTTPS_PORT? (On the Pi running Connect? On each client running the CLI? On all of them?)
  • Which changes do I need to make to the Docker compose file? (if any)
  • How can I verify that HTTPS is used?
  • How can I verify that HTTP is no longer used?

1Password Version: 1Password CLI 2.0.0
Extension Version: n/a
OS Version: Raspberry Pi OS (bullseye, 32 bit)

Comments

  • Joris_1PJoris_1P

    Team Member

    Hi,

    Thanks for reaching out. We're on a continuous journey to improve our docs, so telling us what parts aren't 100% clear is really valuable feedback!

    To help you as well as possible, could you help me understand your specific use-case a bit better?

    1. Should this Connect instance be reachable from the public internet?
    2. If so, do you have a domain that can (or already does) point to the Raspberry Pi?

    This could help me understand whether we can better use Let's Encrypt or create a self-signed TLS-certificate. We can help you out with either option.

    Joris

  • XIIIXIII
    Community Member
    1. I do not want the 1Password Connect server to be publicly available from the internet.
    2. I do have a domain (and a Let's Encrypt wildcard TLS certificate for that domain) that I can redirect to the Pi; either via the (Cloudflare) DNS settings of that domain or via a NextDNS "rewrite" (1p-connect.domain.com -> pi.home.lan?).

    I still want to use TLS on my LAN.

  • XIIIXIII
    Community Member

    I really need your help here!

    This is what I tried:

    For 1Password Connect:

    OP_HTTPS_PORT=18843
    OP_TLS_KEY_FILE=/usr/local/etc/1password/privkey.pem
    OP_TLS_CERT_FILE=/usr/local/etc/1password/cert.pem
    

    For 1Password CLI:

    OP_CONNECT_HOST=https://1password.domain.com:18843
    

    Set up a NextDNS rewrite (mapping the domain name to the IP address of my Raspberry Pi):

    1password.domain.com = 192.168.1.102
    
    ➜ dig +short 1password.domain.com
    192.168.1.102
    

    However:

    op read op://Vault/account/password
    [ERROR] 2022/03/16 22:18:49 could not read secret op://Vault/account/password: could not retrieve vaults: Get "https://1password.domain.com:18843/v1/vaults": http: server gave HTTP response to HTTPS client
    
  • XIIIXIII
    Community Member

    I was hoping this post would help: https://1password.community/discussion/121733/https-support-on-the-api

    I seem to get a little further:

    ➜ journalctl -f -u 1password-connect
    -- Journal begins at Thu 2022-03-10 09:08:15 CET. --
    Mar 16 23:11:13 pi docker-compose[11193]: 1password-connect-sync | {"log_message":"(W) configured to use HTTP with no TLS","timestamp":"2022-03-16T22:11:13.805333444Z","level":2}
    Mar 16 23:11:13 pi docker-compose[11193]: 1password-connect-api | {"log_message":"(I) configured for HTTPS with custom configuration","timestamp":"2022-03-16T22:11:13.872360052Z","level":3}
    Mar 16 23:11:13 pi docker-compose[11193]: 1password-connect-api | {"log_message":"(I) starting 1Password Connect API ...","timestamp":"2022-03-16T22:11:13.873309733Z","level":3}
    Mar 16 23:11:13 pi docker-compose[11193]: 1password-connect-api | {"log_message":"(I) serving on :18843","timestamp":"2022-03-16T22:11:13.873427753Z","level":3}
    

    However:

    ➜ op read op://Vault/account/password
    [ERROR] 2022/03/16 23:16:39 could not read secret op://Vault/account/password: could not retrieve vaults: Get "https://1password.domain.com:18843/v1/vaults": dial tcp 192.168.1.102:18843: connect: connection refused
    

    Note that I have this firewall rule:

    ➜ ufw status
    18843/tcp                  ALLOW       192.168.0.0/16
    
  • XIIIXIII
    Community Member

    @1PBusinessUser Would you be willing to share your setup?

    Unfortunately 1Password has still not documented this and is a bit slow to respond... 😢

  • Joris_1PJoris_1P

    Team Member

    Sorry for the delayed reply. Contrary to most folks at 1Password, I live in Europe. So I sign off a bit earlier than you might be used to from my colleagues.

    I do see you made some great progress! Looking at Connect's logs, it seems to be listening to HTTPS traffic only.

    Could you check if port 18843 is also specified in the docker-compose.yml? Now that Connect is listening on port 18843, we have to make sure that Docker is also forwarding that port. You can do that by changing the ports section of the connect-api container:

    services:
      connect-api:
        # left out some stuff here
        ports:
          - "18843:18843" 
        # left out more stuff here
    

    Let me know if that helps.

    Joris

  • XIIIXIII
    Community Member
    edited March 17

    This post was exactly what I needed. Thanks!

    I was using 18843:8843 instead of 18843:18843... 😲

    It works now!

    PS: I live in Europe too. Good to know that 1Password has a presence in Europe and respects business hours. Maybe I should look for job openings someday...

  • XIIIXIII
    Community Member
    edited March 17

    Partially off-topic, but security related, so I hope it's allowed:

    I would like the *.pem files to only be readable by root, but still share them with the Docker container.

    Is this possible? If so, how? If not, what's the best practice here?

    (I'm relatively new to Docker...)

  • Joris_1PJoris_1P

    Team Member

    It works now!

    Awesome! 🎉

    Partially off-topic, but security related, so I hope it's allowed:

    I would like the *.pem files to only be readable by root, but still share them with the Docker container.

    Is this possible? If so, how? If not, what's the best practice here?

    Of course that is allowed! Unfortunately, it is somewhat of a problematic thing with Docker. There is no way to mount a file with different permissions than on the host. That means that if the file is accessible by root only, the container have to run as root to read the file. The latter is generally considered to be a bad practice. That is also the reason why Connect's images use a custom user.

    What you can give a try though, is: sudo chown 999 <pem-file> and sudo chmod 600 <pem-file>. That will make the user with UID 999 (the UID that is used within Connect's containers) owner of the file and the only user that can read it. Connect should still be able to read the file and any user except for user 999 and root should not be able to read it.

  • XIIIXIII
    Community Member
    edited March 17

    Unfortunately I already have a user with UID 999 for other purposes.

    Maybe I can change that? 🤔 I'm afraid that will break a lot on my Pi...

    https://www.thegeekdiary.com/how-to-correctly-change-the-uid-and-gid-of-a-user-group-in-linux/

    Will I break Connect if I try to change the UID in the container instead, using this?

    user: "<some uid other than 999>:<some gid>"
    
  • Joris_1PJoris_1P

    Team Member

    Will I break Connect if I try to change the UID in the container instead, using this?

    Hmm, I am not sure if that works if the user is not created in Connect first. And I don't think the image has any other users configured.

    Also, technically it should work if the user already exists. The only drawback is that any process running as that user will also have access to the files.

  • XIIIXIII
    Community Member

    Changing the user in the container seems to fail indeed:

    Mar 17 17:40:16 pi-hb docker-compose[3137]: 1password-connect-api | {"log_message":"(I) no database found, will retry in 1s","timestamp":"2022-03-17T16:40:16.350449714Z","level":3}
    

    That's quite unfortunate: this user 999 is already used for software with third-party plugins, so I'd rather not give it access to the *.pem files.

    I might try "swapping" users/UIDs later (if that is possible at all).

  • XIIIXIII
    Community Member

    It only now occurs to me that my existing user 999 is already using the exact same *.pem files...

    However, I'm still not comfortable with it now also getting access to 1password-credentials.json.

    Is there no way to configure the user/group used by your containers? (feature request?)

  • Joris_1PJoris_1P

    Team Member
    edited March 18

    However, I'm still not comfortable with it now also getting access to 1password-credentials.json.

    That is understandable.

    One final thing you can give a try is the following:
    1. Create a directory containing those files (e.g. secrets/)
    2. Move the credential and .pem to this directory.
    3. sudo chown root secrets/: to make the directory owned by root.
    4. sudo chmod 744 secrets/ to only give root execute permission on this directory.
    5. sudo chmod 644 secrets/<file> for all files in the secrets/ directory.

    This should make the files readable in Docker containers, without granting every user on the system access. Why? Only root has the execute permission on the directory, which is needed to read the files in it. So only root can read the files. At least on Linux, Docker is run as root and can therefore open the directory and mount the files. Because the files themselves are still readable by all users (the last 4 in step 5), the containers can still read the files after they are mounted, even though they are not running as root.

    I have tested this on my Fedora Linux system and there it seems to work. Give it a try on your RasPi to see if it also works on there. You can verify access is denied to regular users by running cat secrets/1password-credentials.json. Note that this will probably not work on macOS or Windows because of the way Docker runs on there.

    I will also also record a feature request for some more flexibility in configuring this. If I understand you correctly, having a way to use Docker's user: configuration option would work for you?

    Joris

  • XIIIXIII
    Community Member

    Nice "trick"! Seems to work on my Pi.

    I'm new to Docker, so don't know whether user: would be a (good) solution.

  • XIIIXIII
    Community Member

    PS: Is the https:// scheme in HTTP_CONNECT_HOST needed, or can I achieve using HTTPS in another way?

    OP_CONNECT_HOST=https://1password.domain.com:18843
    

    vs

    OP_CONNECT_HOST=1password.domain.com:18843
    
  • Joris_1PJoris_1P

    Team Member

    Because all plugins and SDK's can be used over either HTTP or HTTPS, the protocol must be specified in OP_CONNECT_HOST. That means that specifying either https:// or http:// is a requirement.

  • XIIIXIII
    Community Member

    Thanks.

    I had some trouble "waiting for" the service at ${OP_CONNECT_HOST} (if it contains the https:// scheme), but it looks like I found a tool to achieve this:

    https://1password.community/discussion/comment/633552/#Comment_633552

  • Joris_1PJoris_1P

    Team Member

    That's great to hear.

This discussion has been closed.