littlebizzy / slickstack

Lightning-fast WordPress on Nginx
https://slickstack.io
GNU General Public License v3.0
624 stars 113 forks source link

Determining correct public IP address and/or overwrite option #171

Closed bari86 closed 1 year ago

bari86 commented 1 year ago

Hi, If I put the VM in a private network and proxy it, then the VM will use private IP as it IPv4 in SS dashboard. This would be wrong then as private IP will not be accessible outside. Is it possible to put IPv4/v6 overwrite in ss-config after installation? Just to overwrite those value shown in WP dashboard. Normal case is autodetect and use the IP, but if needed, can go to ss-config and specify it. Thanks

jessuppi commented 1 year ago

Thanks for the information @bari86

Do you mean a load balancer IP address? Are you suggesting we add a new option in ss-config to save that value, for example something like LOAD_BALANCER_IPV4 perhaps?

I'm not sure overwriting the IPv4 detected by the operating system is a good idea, we may need that in the future. It would be better to keep options more specific I think.

This probably also begs the question if SlickStack should support load balancing in general, and yes it would be great although I'm not sure of all the things we would need to consider for that to happen just yet.

Theoretically, another option like LOAD_BALANCER="true" would probably also need to be added. We are maybe putting the cart before horse discussing IP addresses first, but for a quick fix we could probably do something like above.

jessuppi commented 1 year ago

An update on how SlickStack determines public IP addresses:

SYSTEM_NETWORK_INTERFACE_IPV4=$(ip route get 1.1.1.1 | head -n1 | awk '{print $5}')
SYSTEM_NETWORK_INTERFACE_IPV6=$(ip -6 route get 2606:4700:4700::1111 | head -n1 | awk '{print $5}')

And then:

## ipv4 depends on how network interface is setup (ip vs nickname) ##
if [[ "${SYSTEM_NETWORK_INTERFACE_IPV4}" =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
    SYSTEM_IPV4_ADDRESS="${SYSTEM_NETWORK_INTERFACE_IPV4}"
else
    SYSTEM_IPV4_ADDRESS=$(ip addr show "${SYSTEM_NETWORK_INTERFACE_IPV4}" | grep "inet " | awk '{ print $2;exit }' | cut -d/ -f1)
fi

## ipv6 depends on how network interface is setup (ip vs nickname) ##
if [[ "${SYSTEM_NETWORK_INTERFACE_IPV6}" =~ ^([0-9a-fA-F]{0,4}:){1,7}[0-9a-fA-F]{0,4}$ ]]; then
    SYSTEM_IPV6_ADDRESS="${SYSTEM_NETWORK_INTERFACE_IPV6}"
else
    SYSTEM_IPV6_ADDRESS=$(ip addr show "${SYSTEM_NETWORK_INTERFACE_IPV6}" | grep "inet6 " | awk '{ print $2;exit }' | cut -d/ -f1)
fi

Ref: https://github.com/littlebizzy/slickstack/blob/master/bash/ss-functions.txt

The purpose of retrieving these values is really just to help the user be more aware of them during installation and yes, inside the WP Admin SlickStack dashboard.

SlickStack's OpenSSL script does self-sign a certificate for the detected IP address too.

But none of this is really required for SlickStack to function.

Therefore perhaps @bari86 idea to allow for hardcoding the IPs in ss-config could be acceptable, but it just seems like more cruft you have to worry about fixing in case of server migration, etc.

jessuppi commented 1 year ago

Not sure if these tweaks to our code helped resolve the issue please let me know @bari86

Checking common solutions for the past several years, many devs have been usually private websites to check their VPC public address like described here:

https://stackoverflow.com/questions/14594151/methods-to-detect-public-ip-address-in-bash

E.g.

Also a new answer there that includes some dig methods like:

Those last 2 return IPv6 addresses.

Anyway most of these solutions were before IPv6 got popular and before Cloudflare's 1.1.1.1 service... I think our current method using ip route to Cloudflare's direct DNS server is pretty solid.

jessuppi commented 1 year ago

These might also be simpler methods I tried, but rely on TLDs:

IPv4: dig whoami.cloudflare ch txt @1.1.1.1 +short | awk -F'"' '{print $2}'

IPv6: dig whoami.cloudflare ch txt @2606:4700:4700::1111 +short | awk -F'"' '{print $2}'

Ref: https://gist.github.com/rkalkani/7428a8769f7cc6710c58680938dc5833

jessuppi commented 1 year ago
SYSTEM_DIG_IPV4_ADDRESS=$(dig whoami.cloudflare ch txt @1.1.1.1 +short | awk -F'"' '{print $2}')
SYSTEM_DIG_IPV6_ADDRESS=$(dig whoami.cloudflare ch txt @2606:4700:4700::1111 +short | awk -F'"' '{print $2}')
SYSTEM_NETWORK_INTERFACE_IPV4=$(ip route get 1.1.1.1 | head -n1 | awk '{print $5}')
SYSTEM_NETWORK_INTERFACE_IPV6=$(ip -6 route get 2606:4700:4700::1111 | head -n1 | awk '{print $5}')
SYSTEM_NETWORK_INTERFACE_IPV4_SHOW=$(ip addr show "${SYSTEM_NETWORK_INTERFACE_IPV4}" | grep "inet " | awk '{ print $2;exit }' | cut -d/ -f1)
SYSTEM_NETWORK_INTERFACE_IPV6_SHOW=$(ip addr show "${SYSTEM_NETWORK_INTERFACE_IPV6}" | grep "inet6 " | awk '{ print $2;exit }' | cut -d/ -f1)

Here's an update list of variables we are testing... will probably use the DIG ones primarily.

jessuppi commented 1 year ago

Update:

The new dig method + Cloudflare DNS works very well. For now we are going to use these only:

SYSTEM_DIG_IPV4_ADDRESS=$(dig whoami.cloudflare ch txt @1.1.1.1 +short | awk -F'"' '{print $2}')
SYSTEM_DIG_IPV6_ADDRESS=$(dig whoami.cloudflare ch txt @2606:4700:4700::1111 +short | awk -F'"' '{print $2}')

This should help support complex environments better @bari86

I don't think hardcoding/overwriting is necessary with this improvement, and probably isn't a good idea anyways, because that detection mechanism should ideally remain dynamic to avoid confusion.

On a side note, our OpenSSL cert generator now supports IPV6 addresses along with IPV4:

https://github.com/littlebizzy/slickstack/blob/master/bash/ss-encrypt-openssl.txt

If any comments or questions feel free to respond below, but for now I'm going to close this out --