StreisandEffect / discussions

30 stars 3 forks source link

redeploy server with new public IP #17

Open cpu opened 7 years ago

cpu commented 7 years ago

Suggested by @nickolasclarke in https://github.com/jlund/streisand/issues/184

First off, this is more of a troubleshooting issue than an actual bug, and I do not think this is the most appropriate place for a discussion, but alas, it seems this project does not have a IRC/gitter/mailing list so I'm dropping my problem here. I am currently based in China and I am waging a constant battle against the GFW. While it is hard to confirm definitively (given that results are sporadic on a day to day basis) I believe that often my connections to my streisand instance, no matter what protocol or solution I use, after a few days or even hours get blocked.

For example, right now, while I can SSH to my streisand instance by IP from a jump host and get 0% packet loss from a ping to it from that host, I get around 75% packet loss from my desktop and cannot connect over L2TP/IPSEC or use shadowsocks. However, from my phone I can still successfully connect to the server. While this is not definitive proof, given the constant issues I have with different connections at different locations, I am fairly confident that this is more than simple connectivity issues and is directly related to connection sabotage. the GFW is wildly inconsistent and it is hard to nail down exactly what is causing what.

So, one solution I have found is to simply take a snapshot of a streisand host (I am currently using Digital Ocean Singapore) and then whenever my connection seems to have permanently degraded, I spin a new droplet from the snapshot, modify a few configs files by hand, (such as /home/shadowsocks/config.json:$SERVERVAR) and point my clients at the new IP. This saves having to spin a whole new instance each time, and heavily modify all my client configurations and also seems to fix, albeit temporarily, the problems at hand.

However, I am have not had luck getting l2tp/ipsec to work with this solution, and I have also noticed that the webserver does not seem to be working either. I was hoping to get some help identifying all the requisite configurations that should be modified in order to support a public IP migration since this is the first time I have worked with many of these technologies before. Once I've nailed down the process by hand, I plan to write a tool to quickly redeploy a configured Streisand DO droplet with a new IP which I'll gladly publish here on github.

If there is a better place to publish requests such as these in the future, please let me know and I'll move this to the appropriate forum.

On a related note, being able to backup the full set of Streisand configs and feed them into a deployment would be a great feature, but is outside the scope of this initial request, but I thought I would plant the seed :)

nopdotcom commented 7 years ago

Redeployment is perhaps not quite the right goal. From a user’s point of view, the minimum change is to preserve existing keys, yet regenerate all the docs and config files that have a hardcoded IP address.

It would be great if this could be triggered on the streisand host, but it may be easier to implement as an Ansible task on the original deployment host. (I’m not an Ansible person.)

ridercz commented 6 years ago

It would be better to use host name instead of IP address when possible (when specified during config). Streisand uses host name for getting Let's Encrypt certificate anyway. IP change can be solved by using cloud provider's solution (if any), or independent DDNS service like https://www.freemyip.com/.

nopdotcom commented 6 years ago

One important use case here: server restart in environments where public IP addresses are allocated per-boot.

On AWS, we get a fixed public IP address and it shows up as the address on the network interface.

On Lightsail and some other services, you create the VM, then assign a static IP to the VM in the management interface. (Reboot for safety.) The public IP address shows up on the interface.

On Azure, you can allocate fixed public IP addresses, but that address does not show up as an address on the network interface. Actually, the static IP documentation kinda confuses me. There's an Ansible module for Azure IP addresses.

I'm kinda exhausted with Windows for a while, and I need to work on overdue documentation next. So this is not in my short-term plans, but I will take a look at it as an Ansible exercise eventually.

The pricing structure for Azure is not ideal for Streisand usage. DO and its imitators have 1TB of traffic built into their plans. Vultr has low overage rates as well.

I can imagine that having an endpoint inside Azure might be superior for ingress reachability (it's corporate, so it may not get blanket-banned) and egress reachability (sites that ban proxies may not notice Azure, who knows). Has anybody had experience with this?

ridercz commented 6 years ago

First, this problem is not Azure-specific. For users who don't use Streisand all the time, but only when connected to unreliable networks, makes sense to suspend/undeploy the VM when not in use and spin it up only when needed. Every time it will get different IP address.

Second, Azure may be preferred by users from financial standpoint. At this time, Microsoft has an offer that you can get a small VM (with plenty of computing power for Streisand) for one year for free. Also, developers with Visual Studio subscriptions get some Azure credits included for free. So Azure is for many people good way to get a VM for free or for pennies. Static IP addresses in Azure cost additional money.

Third, what is Azure-specific is that Streisand uses internal IP address of the VM (from 10.x.x.x range), not external one, so following the instructions to the letter won't work. There is a 1:1 NAT and layer for load balancing, the machine isn't directly connected to the Internet with public IP.

All these issues can be solved by using a host name instead of IP address in instruction and profile files, when known. Streisand asks for it and uses it for Let's Encrypt certificate anyway.

I use L2TP/IPsec and OpenVPN and both work just fine with host names without IP address. I'm not sure about other protocols, if there isn't something requiring use of raw IP, but at least for the above mentioned, the problem can be easily solved.

Unfortunatelly, I can't propose direct change and do a pull request, because I don't know Ansible :-(.

nopdotcom commented 6 years ago

I think I need to break this up into a couple of responses, because what you're saying is important. I don't know all this stuff, so it'll take me a little time to work through it.

For my own curiosity, I decided to price unattached IP addresses across providers. I am not saying this is a good deployment strategy, but it can rule out some providers. Like, there's little point in doing this with regular-rate GCE.

Provider Unattached cost/month Local address Notes
Vultr $3 Yes Attached or unattached static IP
Digital Ocean $4 ?
AWS EC2 $4 Yes
AWS Lightsail $4? Yes Presumably EC2 pricing
Azure $2.50 Yes
Google GCE $7 Yes See below
Linode N/A Full price

GCE notes

Google has an Always Free tier. You get a micro instance. Presumably you can attach a static IP address; that avoids the "unattached IP" fee. I haven't tried this yet.

nopdotcom commented 6 years ago

Azure is an OK choice for people already in the Microsoft ecosystem. I haven't had a VS license in a while, so I didn't know about the Azure deal: With Visual Studio Pro you get $50/mon in credits. Annual retail pricing is $539/yr, but many people already have the subscription. I'd be interested in Azure if that were the deal I had too!

Azure deploys break often, because none of us are very good about testing it. I would love to have somebody periodically test it and report.

Right now, deploys to Azure are especially broken because of an upstream Ansible bug. We didn't notice. :-(

nopdotcom commented 6 years ago

Casual examination shows Digital Ocean has "floating IPs" which really are just NAT. So if we want to automatically create persistent IP address on DO, we need some coding.

This is strictly for better experience with VM stop/start; unattached DO floating IPs cost $4/mon, compared to the $5/mon for a running instance.

@ridercz, I'm not an Ansible person either--I'm learning, but I don't expect other people to do so.

If you don't mind setting up another server, it would be helpful to get a diff of your changes in /etc. That's easier than it looks:

# Run as root
# sudo -s
cd /etc
apt-get install etckeeper
git tag begin
# Do your changes here
vi /etc/hosts
date -I >/etc/streisand_build_date
# etc
# Optional: checkpoint your progress
etckeeper commit "Added host entries"

git diff begin
git diff begin >/tmp/diffs

Given that, I bet I can we can make something happen in Ansible.

rdbox commented 6 years ago

I did not understand the solution found? There is a lot of information, but I do not see a solution?????

ghost commented 6 years ago

Also looking for a solution

rdbox commented 6 years ago

To mean while there is a hard decision it to search for coincidence ip server and to replace on new ip. The other solutions did not find

sed -i -- 's/foo/bar/g' *
perl -i -pe 's/foo/bar/g' ./* 

and another option

grep -rli 'old-word' * | xargs -i@ sed -i 's/old-word/new-word/g' @

maybe someone will be out of the developers and come up with an automatic script