Compare commits

...

4 Commits

3 changed files with 42 additions and 31 deletions

View File

@ -1,7 +1,7 @@
---
title: "Gitea: Ultralight Self-Hosted Git Server" # Title of the blog post.
date: 2022-07-22 # Date of post creation.
lastmod: 2022-07-27
lastmod: 2023-01-19
description: "Deploying the lightweight Gitea Git server on Oracle Cloud's free Ampere Compute."
featured: false # Sets if post is a featured post, making appear on the home page side bar.
draft: false # Sets whether to render this page. Draft of true will not be rendered.
@ -217,7 +217,7 @@ services:
- GITEA__repository__DEFAULT_PRIVATE=private
- GITEA__repository__DISABLE_HTTP_GIT=true
- GITEA__server__DOMAIN=git.bowdre.net
- GITEA__server__SSH_DOMAIN=git.bowdre.net.beta.tailscale.net
- GITEA__server__SSH_DOMAIN=git.tadpole-jazz.ts.net
- GITEA__server__ROOT_URL=https://git.bowdre.net/
- GITEA__server__LANDING_PAGE=explore
- GITEA__service__DISABLE_REGISTRATION=true
@ -239,7 +239,7 @@ services:
- db
db:
image: postgres:latest
image: postgres:14
container_name: gitea_db
restart: always
environment:
@ -251,6 +251,9 @@ services:
volumes:
- ./postgres:/var/lib/postgresql/data
```
{{% notice info "Pin the PostgreSQL version" %}}
The format of PostgreSQL data changes with new releases, and that means that the data created by different major releases are not compatible. Unless you take steps to upgrade the data format, you'll have problems when a new major release of PostgreSQL arrives. Avoid the headache: pin this to a major version (as I did with `image: postgres:14` above) so you can upgrade on your terms.
{{% /notice %}}
Let's go through the extra configs in a bit more detail:
| Variable setting | Purpose |
@ -264,7 +267,7 @@ Let's go through the extra configs in a bit more detail:
|`GITEA__repository__DEFAULT_PRIVATE=private` | All repos will default to private unless I explicitly override that |
|`GITEA__repository__DISABLE_HTTP_GIT=true` | Require that all Git operations occur over SSH |
|`GITEA__server__DOMAIN=git.bowdre.net` | Domain name of the server |
|`GITEA__server__SSH_DOMAIN=git.bowdre.net.beta.tailscale.net` | Leverage Tailscale's [MagicDNS](https://tailscale.com/kb/1081/magicdns/) to tell clients how to SSH to the Tailscale internal IP |
|`GITEA__server__SSH_DOMAIN=git.tadpole-jazz.ts.net` | Leverage Tailscale's [MagicDNS](https://tailscale.com/kb/1081/magicdns/) to tell clients how to SSH to the Tailscale internal IP |
|`GITEA__server__ROOT_URL=https://git.bowdre.net/` | Public-facing URL |
|`GITEA__server__LANDING_PAGE=explore` | Defaults to showing the "Explore" page (listing any public repos) instead of the "Home" page (which just tells about the Gitea project) |
|`GITEA__service__DISABLE_REGISTRATION=true` | New users will not be able to self-register for access; they will have to be manually added by the Administrator account that will be created during the initial setup |
@ -462,7 +465,7 @@ You might noticed that I unchecked the *Make Repository Private* option for this
The real point of this whole exercise was to sync my Obsidian vault to a Git server under my control, so it's time to create a place for that content to live. I'll go to the **+** menu again but this time select **New Repository**, and then enter the required information:
![New repository](new_repository.png)
Once it's created, the new-but-empty repository gives me instructions on how I can interact with it. Note that the SSH address uses the special `git.bowdre.net.beta.tailscale.net` Tailscale domain name which is only accessible within my tailnet.
Once it's created, the new-but-empty repository gives me instructions on how I can interact with it. Note that the SSH address uses the special `git.tadpole-jazz.ts.net` Tailscale domain name which is only accessible within my tailnet.
![Emtpy repository](empty_repo.png)
@ -473,7 +476,7 @@ cd ~/obsidian-vault/
git init
git add .
git commit -m "initial commit"
git remote add origin git@git.bowdre.net.beta.tailscale.net:john/obsidian-vault.git
git remote add origin git@git.tadpole-jazz.ts.net:john/obsidian-vault.git
git push -u origin main
```

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

View File

@ -1,17 +1,17 @@
---
title: "Tailscale golink: Private Shortlinks for your Tailnet" # Title of the blog post.
date: 2023-01-08T13:51:42-06:00 # Date of post creation.
date: 2023-02-12
# lastmod: 2023-01-08T13:51:42-06:00 # Date when last modified
description: "How to deploy Tailscale's golink service in a Docker container."
featured: false # Sets if post is a featured post, making appear on the home page side bar.
draft: true # Sets whether to render this page. Draft of true will not be rendered.
draft: false # Sets whether to render this page. Draft of true will not be rendered.
toc: true # Controls if a table of contents should be generated for first-level links automatically.
usePageBundles: true
# menu: main
# featureImage: "file.png" # Sets featured image on blog post.
# featureImageAlt: 'Description of image' # Alternative text for featured image.
# featureImageCap: 'This is the featured image.' # Caption (optional).
# thumbnail: "thumbnail.png" # Sets thumbnail image appearing inside card on homepage.
thumbnail: "golinks.png" # Sets thumbnail image appearing inside card on homepage.
# shareImage: "share.png" # Designate a separate image for social media sharing.
codeLineNumbers: false # Override global value for showing of line numbers within code block.
series: Tips # Projects, Scripts, vRA8, K8s on vSphere
@ -23,16 +23,16 @@ tags:
- containers
comment: true # Disable comment if false.
---
I've shared in the past about how I use [custom search engines in Chrome](/abusing-chromes-custom-search-engines-for-fun-and-profit/) as quick web shortcuts. And I may have mentioned [my love for Tailscale](/tags/tailscale/) a time or two as well. Well I recently learned of a way to combine these two passions: [Tailscale golink](https://github.com/tailscale/golink). The [golink announcement poston the Tailscale blog](https://tailscale.com/blog/golink/) offers a great overview of the service:
> Using golink, you can create and share simple go/name links for commonly accessed websites, so that anyone in your network can access them no matter the device theyre on — without requiring browser extensions or fiddling with DNS settings. And because golink integrates with Tailscale, links are private to users in your tailnet without any separate user management, logins, or security policies.
I've shared in the past about how I use [custom search engines in Chrome](/abusing-chromes-custom-search-engines-for-fun-and-profit/) as quick web shortcuts. And I may have mentioned [my love for Tailscale](/tags/tailscale/) a time or two as well. Well I recently learned of a way to combine these two passions: [Tailscale golink](https://github.com/tailscale/golink). The [golink announcement post on the Tailscale blog](https://tailscale.com/blog/golink/) offers a great overview of the service:
> Using golink, you can create and share simple go/name links for commonly accessed websites, so that anyone in your network can access them no matter the device theyre on — without requiring browser extensions or fiddling with DNS settings. And because golink integrates with Tailscale, links are private to users in your tailnet without any separate user management, logins, or security policies.
And these go links don't have to be simply static shortcuts; the system is able to leverage go templates to conditionally insert text into the target URL - similar to my custom search engine setup. The Tailscale blog also has some clever suggestions on how to use this capability.
And these go links don't have to be simply static shortcuts either; they can also conditionally insert text into the target URL - similar to my custom search engine setup. The Tailscale blog also has some clever suggestions on how to use this capability.
Sounds great - but how do you actually make golink available on your tailnet? Well, here's what I did to deploy the [golink Docker image](https://github.com/tailscale/golink/pkgs/container/golink) on a [Photon OS VM I set up running on my Quartz64 running ESXi-ARM](/esxi-arm-on-quartz64/#workload-creation).
## Tailnet prep
There are three things I'll need to do in the Tailscale admin portal before moving on.
### Create an ACL tag
### Tailnet prep
There are three things I'll need to do in the Tailscale admin portal before moving on:
#### Create an ACL tag
I assign ACL tags to devices in my tailnet based on their location and/or purpose, and I'm then able to use those in a policy to restrict access between certain devices. To that end, I'm going to create a new `tag:golink` tag for this purpose. Creating a new tag in Tailscale is really just going to the [Access Controls page of the admin console](https://login.tailscale.com/admin/acls) and editing the policy to specify a `tagOwner` who is permitted to assign the tag:
```text {hl_lines=[11]}
"groups":
@ -49,10 +49,10 @@ I assign ACL tags to devices in my tailnet based on their location and/or purpos
},
```
### Configure ACL access
#### Configure ACL access
This step is really only necessary since I've altered the default Tailscale ACL and prevent my nodes from communicating with each other unless specifically permitted. I want to make sure that everything on my tailnet can access golink:
```text
```text
"acls": [
{
// make golink accessible to everything
@ -66,8 +66,8 @@ This step is really only necessary since I've altered the default Tailscale ACL
],
```
### Create an auth key
The last prerequisite task is to create a new authentication key that the golink container can use to log in to Tailscale since I won't be running `tailscale` interactively. This can easily be done from the [Settings page](https://login.tailscale.com/admin/settings/keys). I'll go ahead and set the key to expire in 1 day (since I'm going to use it in just a moment), make sure that the Epheral option is _disabled_ (since I don't want the new node to lose its authorization once it disconnects), and associate it with my new `tag:golink` tag.
#### Create an auth key
The last prerequisite task is to create a new authentication key that the golink container can use to log in to Tailscale since I won't be running `tailscale` interactively. This can easily be done from the [Settings page](https://login.tailscale.com/admin/settings/keys). I'll go ahead and set the key to expire in 1 day (since I'm going to use it in just a moment), make sure that the Ephemeral option is _disabled_ (since I don't want the new node to lose its authorization once it disconnects), and associate it with my new `tag:golink` tag.
![Creating a new auth key](create_auth_key.png)
@ -76,7 +76,7 @@ Applying that tag does two things for me: (1) it makes it easy to manage access
After clicking the **Generate key** button, the key will be displayed. This is the only time it will be visible so be sure to copy it somewhere safe!
## Docker setup
### Docker setup
The [golink repo](https://github.com/tailscale/golink) offers this command for running the container:
```shell
docker run -it --rm ghcr.io/tailscale/golink:main
@ -87,7 +87,7 @@ The doc also indicates that I can pass the auth key to the golink service via th
```shell
mkdir -p golink/data
cd golink
chmod 65536:65563 data
chmod 65532:65532 data
vi docker-compose.yaml
```
@ -106,17 +106,20 @@ services:
```
I can then start the container with `sudo docker-compose up -d`, and check the Tailscale admin console to see that the new machine was registered successfully:
![Newly registered machine](registed_machine.png)
![Newly registered machine](registered_machine.png)
And I can point a web browser to `go/` and see the (currently-empty) landing page:
![Empty go page](empty_go_page.png)
{{% notice tip "Security cleanup!" %}}
The `TS_AUTHKEY` is only needed for this initial authentication; now that the container is connected to my Tailnet I can remove that line from the `docker-compose.yaml` file to avoid having a sensitive credential hanging around. Future (re)starts of the container will use the token stored in the golink database.
{{% /notice %}}
## Get go'ing
### Get go'ing
Getting started with golink is pretty simple - just enter a shortname and a destination:
![Creating a new link](create_new_link.png)
So now when I enter `go/vcenter` it will automatically take me to the vCenter in my homelab. That's handy... but we can do better. You see, golink also supports Go template syntax, which allows it to behave a bit like those custom search engines I mentioned earlier.
So now when I enter `go/vcenter` it will automatically take me to the vCenter in my homelab. That's handy... but we can do better. You see, golink also supports Go template syntax, which allows it to behave a bit like those custom search engines I mentioned earlier.
I can go to `go/.detail/LINK_NAME` to edit the link, so I hit up `go/.detail/vcenter` and add a bit to the target URL:
```
@ -129,17 +132,22 @@ Some of my other golinks:
| Shortlink | Destination URL | Description |
| --- | --- | --- |
| `cs` | `https://github.com/search?type=code&q=user:jbowdre+{{with .Path}}+{{.}}{{end}}` | searches my code on Github |
| `ipam` | `https://ipam.lab.bowdre.net/{{with .Path}}tools/search/{{.}}{{end}}` | searches my phpIPAM instance |
| `code` | `https://github.com/search?type=code&q=user:jbowdre{{with .Path}}+{{.}}{{end}}` | searches my code on Github |
| `ipam` | `https://ipam.lab.bowdre.net/{{with .Path}}tools/search/{{.}}{{end}}` | searches my lab phpIPAM instance |
| `pdb` | `https://www.protondb.com/{{with .Path}}search?q={{.}}{{end}}` | searches [protondb](https://www.protondb.com/), super-handy for checking game compatibility when [Tailscale is installed on a Steam Deck](https://tailscale.com/blog/steam-deck/) |
| `tailnet` | `https://login.tailscale.com/admin/machines?q={{.Path}}` | searches my Tailscale admin panel for a machine name |
| `vpot8` | `https://www.virtuallypotato.com/{{with .Path}}search?query={{.}}{{end}}` | searches this here site |
| `sho` | `https://www.shodan.io/{{with .Path}}search?query={{.}}{{end}}` | searches Shodan for interesting internet-connected systems |
| `tools` | `https://neeva.com/spaces/m_Bhx8tPfYQbOmaW1UHz-3a_xg3h2amlogo2GzgD` | shortcut to my [Tech Toolkit space](https://neeva.com/spaces/m_Bhx8tPfYQbOmaW1UHz-3a_xg3h2amlogo2GzgD) on Neeva |
## Back up and restore
You can browse to `go/.export` to see a JSON-formatted listing of all configured shortcuts - or, if you're clever, you could do something like `curl http://go/.export -o links.json` to download a copy.
#### Back up and restore
You can browse to `go/.export` to see a JSON-formatted listing of all configured shortcuts - or, if you're clever, you could do something like `curl http://go/.export -o links.json` to download a copy.
To restore, just pass `--snapshot /path/to/links.json` when starting golink. What I usually do is copy the file into the `data` folder that I'm mounting as a Docker volume, and then just run:
```shell
sudo docker exec -it golink /golink --sqlitedb /home/nonroot/golink.db --snapshot /home/nonroot/links.json
sudo docker exec golink /golink --sqlitedb /home/nonroot/golink.db --snapshot /home/nonroot/links.json
```
### Conclusion
This little golink utility has been pretty handy on my Tailnet so far. It seems so simple, but I'm really impressed by how well it works. If you happen to try it out, I'd love to hear how you're putting it to use.