Handle port bindings correctly when using 127.0.0.1

closes pterodactyl/panel#2307
This commit is contained in:
Dane Everitt 2020-09-07 15:33:47 -07:00
parent 77cf57d1ea
commit 5bead443ad
No known key found for this signature in database
GPG Key ID: EEA66103B3D71F53
3 changed files with 46 additions and 4 deletions

View File

@ -3,6 +3,7 @@ package environment
import (
"fmt"
"github.com/docker/go-connections/nat"
"github.com/pterodactyl/wings/config"
"strconv"
)
@ -25,6 +26,8 @@ type Allocations struct {
// Converts the server allocation mappings into a format that can be understood by Docker. While
// we do strive to support multiple environments, using Docker's standardized format for the
// bindings certainly makes life a little easier for managing things.
//
// You'll want to use DockerBindings() if you need to re-map 127.0.0.1 to the Docker interface.
func (a *Allocations) Bindings() nat.PortMap {
var out = nat.PortMap{}
@ -50,16 +53,47 @@ func (a *Allocations) Bindings() nat.PortMap {
return out
}
// Returns the bindings for the server in a way that is supported correctly by Docker. This replaces
// any reference to 127.0.0.1 with the IP of the pterodactyl0 network interface which will allow the
// server to operate on a local address while still being accessible by other containers.
func (a *Allocations) DockerBindings() nat.PortMap {
iface := config.Get().Docker.Network.Interface
out := a.Bindings()
// Loop over all of the bindings for this container, and convert any that reference 127.0.0.1
// to use the pterodactyl0 network interface IP, as that is the true local for what people are
// trying to do when creating servers.
for p, binds := range out {
for i, alloc := range binds {
if alloc.HostIP != "127.0.0.1" {
continue
}
// If using ISPN just delete the local allocation from the server.
if config.Get().Docker.Network.ISPN {
out[p] = append(out[p][:i], out[p][i+1:]...)
} else {
out[p][i] = nat.PortBinding{
HostIP: iface,
HostPort: alloc.HostPort,
}
}
}
}
return out
}
// Converts the server allocation mappings into a PortSet that can be understood
// by Docker. This formatting is slightly different than "Bindings" as it should
// return an empty struct rather than a binding.
//
// To accomplish this, we'll just get the values from "Bindings" and then set them
// To accomplish this, we'll just get the values from "DockerBindings" and then set them
// to empty structs. Because why not.
func (a *Allocations) Exposed() nat.PortSet {
var out = nat.PortSet{}
for port := range a.Bindings() {
for port := range a.DockerBindings() {
out[port] = struct{}{}
}

View File

@ -164,7 +164,7 @@ func (e *Environment) Create() error {
tmpfsSize := strconv.Itoa(int(config.Get().Docker.TmpfsSize))
hostConf := &container.HostConfig{
PortBindings: a.Bindings(),
PortBindings: a.DockerBindings(),
// Configure the mounts for this container. First mount the server data directory
// into the container as a r/w bind.

View File

@ -6,6 +6,7 @@ import (
"github.com/apex/log"
"github.com/pkg/errors"
"github.com/pterodactyl/wings/api"
"github.com/pterodactyl/wings/config"
"github.com/pterodactyl/wings/environment"
"github.com/pterodactyl/wings/environment/docker"
"github.com/pterodactyl/wings/events"
@ -74,11 +75,18 @@ func (s *Server) Id() string {
func (s *Server) GetEnvironmentVariables() []string {
zone, _ := time.Now().In(time.Local).Zone()
var ip = s.Config().Allocations.DefaultMapping.Ip
// Convert 127.0.0.1 to the pterodactyl0 network interface if the environment is Docker
// so that the server operates as expected.
if s.Environment.Type() == "docker" && ip == "127.0.0.1" {
ip = config.Get().Docker.Network.Interface
}
var out = []string{
fmt.Sprintf("TZ=%s", zone),
fmt.Sprintf("STARTUP=%s", s.Config().Invocation),
fmt.Sprintf("SERVER_MEMORY=%d", s.MemoryLimit()),
fmt.Sprintf("SERVER_IP=%s", s.Config().Allocations.DefaultMapping.Ip),
fmt.Sprintf("SERVER_IP=%s", ip),
fmt.Sprintf("SERVER_PORT=%d", s.Config().Allocations.DefaultMapping.Port),
}