8 ms·
Show HN: I made an SSH tunnel manager to learn Go
- leroman 2y agoThe title was so confusing to me, the reason I opened the link was to understand how you made the SSH tunnel manager learn the GO programming language
- michaelmcdonald 2y agoTo be fair: it is a "Show HN" title (which I believe is typically used to denote a project being "shown [off]" by the op).
- kaashif 2y agoI don't think the title is confusing, if that were the desired meaning then it'd say "I made an SSH tunnel manager learn Go" i.e. no "to". I don't think "I made X to do Y" ever means "I made X do Y" does it?
- Veen 2y agoNot for native speakers, but I've heard non-native speakers use "I made X to do Y" in that way.
- madeforhnyo 2y agoNice project! I would advise to use $XDG_CONFIG_HOME instead of $HOME for storing the configuration file though :)
- porridgeraisin 2y agoI hate XDG stuff so much. I just wish every app had their own folder in which they can put whatever they want. If home directory clutter is the issue, then just ~/crap/.{app1,..n} can be standardised. Basically, I want app/kinds-of-data and not the other way around.
- jasonjayr 2y ago$XDG_CONFIG_HOME is usually "~/.config/{app1,...n}" so, it's close? Plus it allows a user to redirect it to a path of their choice, if all apps used it to begin with. Don't get me wrong -- some of the choices made by the XDG/FreeDesktop folks rub me the wrong way too ...
- sevg 2y agoNo, not quite. XDG-compliant programs end up storing stuff in one or more of the following places: ~/.cache and ~/.config and ~/.local/share and ~/.local/state and ~/.local/bin I used to get annoyed by non-compliance to XDG. Now I wonder if I'd actually prefer apps to reverse the hierarchy (eg, ~/.apps/nvim/{cache,config,state}).
- nat 2y agoI would definitely prefer this. I've never wanted to see the "cache" stores for all (XDG-compliant) apps, but often want to see everything for a single app.
- eadmund 2y agoIt’s less about wanting to see all the caches, and more about excluding all the caches, e.g. from backups. Likewise, there is one directory for machine-independent configuration which you might share, and another for machine-specific state (such as window positions). Is the spec perfect? No, of course not. But is it thoughtful, and does it address genuine needs? Yes, certainly.
- jasonjayr 2y agoIt also enables you do things like: a) store caches & libdata on different disk b) consistently 'reset' cached data for kiosk style logins c) make config read-only, or reset to a known good state d) Roaming profiles where the cache is excluded from sync across machines Most computers + home directories are 'personal' where this largly doesn't matter, but there are often sound operational reasons for this seperation in cases where you are responsible for a fleet of computers. I too perfer the 'everything related to this app in one dir' approach. Crazy idea: for apps adhering to XDG, you could point all these vars at a directory under a FUSE-style mount, which then remaps the storage any way you'd like. :)
- perbu 2y agoIs XDG_CONFIG_HOME Unix? Isn't it just some Linux convention?
- deleted 2y ago[deleted]
- wrs 2y agoXDG = X (pronounced “cross”) Desktop Group, aka freedesktop.org, promulgator of conventions for desktop apps. So, neither one really.
- 0xbadcafebee 2y agoYeah, I'm gonna stick with POSIX. All systems I'm aware of (other than Linux Desktop apps) use $HOME. If you want to extend your functionality to use an OS-specific directory, that's fine, but $HOME is the safest default. (Same for things like $TMPDIR)
- spauldo 2y agoNone of that is defined in POSIX, hence the perceived need for XDG.
- 0xbadcafebee 2y agoIt is: https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/V1_chap08.html https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/V1...
- xorcist 2y agoXDG is so bad. There was actually a working best practice before those people came around. Not only did they fragment the ecosystem with their self-defined standards, their standard contains a whole search path with the priority hierarchy baggage, but unspecified enough that all software does it differently. Just ignore it and pretend it doesn't exist.
- miguelfernandez 2y agoNice work! SSH tunnels can be a pain, so this looks handy. What was the toughest part of building it in Go? Any features you’re thinking of adding?
- 0x12A 2y agoI agree! Honestly, Go made building this quite pleasant, as it has nice abstractions for networking and a great concurrency model. I'm planning to keep it minimal for now, but I would like to add Windows support, SSH multiplexing and maybe some form of throughput measurement. But I'm open to ideas :)
- KnowtheRopes 2y agoAh, I just started learning Go, and this project looks awesome! I hope I can write something like this in a couple of months too! Well done!
- 0x12A 2y agoThank you. I found that you can get really productive quite fast in Go, so happy learning :)
- perbu 2y agoWell done. The ease of use and high quality of the Go SSH libraries (golang.org/x/crypto/ssh) is a killer feature of Go, imho. Also, there is a high level abstraction, github.com/gliderlabs/ssh, which makes it completely trivial to embed an ssh server into an application, giving you a nice way to inspect counters and flip feature flags and tuneables.
- tracker1 2y agoDefinitely... first became roughly aware of it with the doorparty connector service[1]. Which is a niche fit, but definitely was cool to see how it worked. 1. https://github.com/echicken/dpc2/ https://github.com/echicken/dpc2/
- evanelias 2y agoThe only major downside to golang.org/x/crypto/ssh is that open issues seem to linger for years lately, even when people try to submit patches. So it's often necessary to look for third-party solutions. The knownhosts handling in particular has a bunch of common land-mines. I'm the maintainer of a wrapper package https://github.com/skeema/knownhosts/ https://github.com/skeema/knownhosts/ which solves some of them, without having to re-implement the core knownhosts logic from x/crypto/ssh. Just to illustrate how common these land-mines are, my wrapper package is imported by 8000 other repos on GitHub, although most of these are indirect dependencies: https://github.com/skeema/knownhosts/network/dependents https://github.com/skeema/knownhosts/network/dependents
- deleted 2y ago[deleted]
- 0xbadcafebee 2y agoI think in an ideal world, this would be the normal case. A hierarchy of packages, maintained by many independent parties, that extend useful base functionality, without too much logic being put in any one package. If one thing doesn't work well you can just create a new package to replace the one part. And building on top of simpler, smaller modules allows you to keep code DRY, reduce maintenance burden (like the 1000 open PRs...), and easily extend functionality by simply making a new package. That was my experience with CPAN, anyway. It's not perfect but it's miles above other language module cultures.
- tempfile 2y agooh, sweet, I was planning to do something like this, now I don't have to
- jaimehrubiks 2y agoThis looks so good! I have two questions 1. What happens if the tunnels breaks? Does it retry instantly? Is there any sort of exponential backlog time? Just wondering if the server is down, if it would spike the cpu or would be gentle (while still fast enough) 2. Would you be adding support for Socks Proxy? The ssh command is quite simple, and it is as useful as regular remote and local tunnels.
- 0x12A 2y agoThank you! Yes, there is an exponential backoff strategy for reconnection attempts. Supporting SOCKS sounds like a nice idea, I'll look into it!
- 0xbadcafebee 2y agoI think there are a couple packages out there for using Websockets to proxy a tcp connection, and some of them support SOCKS. I think they all overload that Dialup function as a generic way of opening connections
- SG- 2y agonice app, i was actually going to make a version of this with a small macos ui myself using a menu item.
- ubanholzer 2y agoWell done! if you want to extend your CLI UI, check out Bubble Tea (https://github.com/charmbracelet/bubbletea https://github.com/charmbracelet/bubbletea)
- collinvandyck76 2y agoAfter having spent the last year writing rust, it's a breath of fresh air to clone and read through a concise and straightforward repo like this.
- CBarkleyU 2y agoIs Rust still that hard to grok even after a year to you? This is by no means meant to be disrespectful but I'm itching to start learning Rust but having only worked in Python/C#/Go I'm getting cold feet just looking at a Rust codebase Disclaimer: I'm usually very good at hitting the ground running, but I am just as much bad at "keeping the pace", i.e. diving deep into stuff
- devsda 2y ago> I'm usually very good at hitting the ground running, but I am just as much bad at "keeping the pace", i.e. diving deep into stuff At a beginner level, rustlings[1] is an excellent resource for following along with any book/tutorial and do relevant exercise to apply the concepts from the learning material. On a more higher level, I guess (re)implementing some tool that you use daily is another way to deep dive into rust. I suspect it's one of the reasons why we see an unusual number of "rewrite of x in rust" projects. [1]. https://github.com/rust-lang/rustlings https://github.com/rust-lang/rustlings
- collinvandyck76 2y agoI wouldn't say that it's hard to grok.. even a year ago I found that rust projects lent themselves well towards understanding the project structure due to rust being fairly explicit about most things, and with an LSP integration I could follow along fairly easily compared to something like a python or a ruby project. Go is just easier to read. You don't have a lot of generics typically to assemble in your mental model, no lifetimes to consider, no explicit interface implementations, and so on. All of those things in Rust are great for what they do, but I think it makes it more difficult to breeze through a codebase compared to Go.
- sureglymop 2y agoFor me it's not the language concepts that are hard, it's that things are sometimes very different and if you come from other languages it's easy to make wrong assumptions. One resource I would highly recommend after the basic stuff people always recommend is a book called "Learn Rust With Entirely Too Many Linked Lists".
- richbray 2y agoI've been meaning to learn Go for a while. This looks like a nice project to go through and pick up a few techniques.
- sirjaz 2y agoAny plans for windows support?
- 0x12A 2y agoYes, it's in my backlog, but I don't have a concrete timeline as of now.
- flustercan 2y agoWhat would one do with a command line SSH tunnel manager?
- dvektor 2y agoSo what do you think of Go after the project? What language(s) did you come from?
- 0x12A 2y agoIMO, it hits a nice sweet spot between performance and level of abstraction, especially w.r.t. concurrency and networking. Also I found that you get things done incredibly fast. I am mostly doing Python and some C, so Go feels like "somewhere in between".
- coumbaya 2y agoIf you don't mind a few small advices: don't use global variables that you mutate, prefer structs with methods. Add a main context with signal.NotifyContext to globally handle sigkill/sigterm and have a gracefull shutdown. Also use DialContext when available instead of Dial. You could use errGroup to handle multiple goroutines that return errors (rather than iterating on a channel). Otherwise it looks good, great job !
- 0x12A 2y agoGreat, thanks for the advice!