mirror of
				https://github.com/owncast/owncast.git
				synced 2025-11-01 02:44:31 +08:00 
			
		
		
		
	* Fix #981 Use -webserverip to set http listen address * use 0.0.0.0 as default http listen address * add Admin REST API for setting http listen address * full input validation of port and IP
This commit is contained in:
		| @ -21,6 +21,9 @@ var VersionNumber = StaticVersionNumber | |||||||
| // WebServerPort is the port for Owncast's webserver that is used for this execution of the service. | // WebServerPort is the port for Owncast's webserver that is used for this execution of the service. | ||||||
| var WebServerPort = 8080 | var WebServerPort = 8080 | ||||||
|  |  | ||||||
|  | // Bind WebServer to this IP address. Be secure by default. | ||||||
|  | var WebServerIP = "0.0.0.0" | ||||||
|  |  | ||||||
| // InternalHLSListenerPort is the port for HLS writes that is used for this execution of the service. | // InternalHLSListenerPort is the port for HLS writes that is used for this execution of the service. | ||||||
| var InternalHLSListenerPort = "8927" | var InternalHLSListenerPort = "8927" | ||||||
|  |  | ||||||
|  | |||||||
| @ -14,6 +14,7 @@ type Defaults struct { | |||||||
|  |  | ||||||
| 	DatabaseFilePath string | 	DatabaseFilePath string | ||||||
| 	WebServerPort    int | 	WebServerPort    int | ||||||
|  | 	WebServerIP      string | ||||||
| 	RTMPServerPort   int | 	RTMPServerPort   int | ||||||
| 	StreamKey        string | 	StreamKey        string | ||||||
|  |  | ||||||
| @ -46,6 +47,7 @@ func GetDefaults() Defaults { | |||||||
| 		YPServer:  "https://directory.owncast.online", | 		YPServer:  "https://directory.owncast.online", | ||||||
|  |  | ||||||
| 		WebServerPort:  8080, | 		WebServerPort:  8080, | ||||||
|  | 		WebServerIP:    "0.0.0.0", | ||||||
| 		RTMPServerPort: 1935, | 		RTMPServerPort: 1935, | ||||||
| 		StreamKey:      "abc123", | 		StreamKey:      "abc123", | ||||||
|  |  | ||||||
|  | |||||||
| @ -5,6 +5,7 @@ import ( | |||||||
| 	"encoding/json" | 	"encoding/json" | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"io/ioutil" | 	"io/ioutil" | ||||||
|  | 	"net" | ||||||
| 	"net/http" | 	"net/http" | ||||||
| 	"path/filepath" | 	"path/filepath" | ||||||
| 	"reflect" | 	"reflect" | ||||||
| @ -293,12 +294,48 @@ func SetWebServerPort(w http.ResponseWriter, r *http.Request) { | |||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if err := data.SetHTTPPortNumber(configValue.Value.(float64)); err != nil { | 	if port, ok := configValue.Value.(float64); ok { | ||||||
| 		controllers.WriteSimpleResponse(w, false, err.Error()) | 		if (port < 1) || (port > 65535) { | ||||||
|  | 			controllers.WriteSimpleResponse(w, false, "Port number must be between 1 and 65535") | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  | 		if err := data.SetHTTPPortNumber(port); err != nil { | ||||||
|  | 			controllers.WriteSimpleResponse(w, false, err.Error()) | ||||||
|  | 			return | ||||||
|  | 		} else { | ||||||
|  | 			controllers.WriteSimpleResponse(w, true, "HTTP port set") | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	controllers.WriteSimpleResponse(w, false, "Invalid type or value, port must be a number") | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // SetWebServerIP will handle the web config request to set the server's HTTP listen address. | ||||||
|  | func SetWebServerIP(w http.ResponseWriter, r *http.Request) { | ||||||
|  | 	if !requirePOST(w, r) { | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	controllers.WriteSimpleResponse(w, true, "http port set") | 	configValue, success := getValueFromRequest(w, r) | ||||||
|  | 	if !success { | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if input, ok := configValue.Value.(string); ok { | ||||||
|  | 		if ip := net.ParseIP(input); ip != nil { | ||||||
|  | 			if err := data.SetHTTPListenAddress(ip.String()); err != nil { | ||||||
|  | 				controllers.WriteSimpleResponse(w, false, err.Error()) | ||||||
|  | 				return | ||||||
|  | 			} else { | ||||||
|  | 				controllers.WriteSimpleResponse(w, true, "HTTP listen address set") | ||||||
|  | 				return | ||||||
|  | 			} | ||||||
|  | 		} else { | ||||||
|  | 			controllers.WriteSimpleResponse(w, false, "Invalid IP address") | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	controllers.WriteSimpleResponse(w, false, "Invalid type or value, IP address must be a string") | ||||||
| } | } | ||||||
|  |  | ||||||
| // SetRTMPServerPort will handle the web config request to set the inbound RTMP port. | // SetRTMPServerPort will handle the web config request to set the inbound RTMP port. | ||||||
|  | |||||||
| @ -46,6 +46,7 @@ func GetServerConfig(w http.ResponseWriter, r *http.Request) { | |||||||
| 		FFmpegPath:     ffmpeg, | 		FFmpegPath:     ffmpeg, | ||||||
| 		StreamKey:      data.GetStreamKey(), | 		StreamKey:      data.GetStreamKey(), | ||||||
| 		WebServerPort:  config.WebServerPort, | 		WebServerPort:  config.WebServerPort, | ||||||
|  | 		WebServerIP:    config.WebServerIP, | ||||||
| 		RTMPServerPort: data.GetRTMPPortNumber(), | 		RTMPServerPort: data.GetRTMPPortNumber(), | ||||||
| 		ChatDisabled:   data.GetChatDisabled(), | 		ChatDisabled:   data.GetChatDisabled(), | ||||||
| 		VideoSettings: videoSettings{ | 		VideoSettings: videoSettings{ | ||||||
| @ -75,6 +76,7 @@ type serverConfigAdminResponse struct { | |||||||
| 	FFmpegPath        string                  `json:"ffmpegPath"` | 	FFmpegPath        string                  `json:"ffmpegPath"` | ||||||
| 	StreamKey         string                  `json:"streamKey"` | 	StreamKey         string                  `json:"streamKey"` | ||||||
| 	WebServerPort     int                     `json:"webServerPort"` | 	WebServerPort     int                     `json:"webServerPort"` | ||||||
|  | 	WebServerIP       string                  `json:"webServerIP"` | ||||||
| 	RTMPServerPort    int                     `json:"rtmpServerPort"` | 	RTMPServerPort    int                     `json:"rtmpServerPort"` | ||||||
| 	S3                models.S3               `json:"s3"` | 	S3                models.S3               `json:"s3"` | ||||||
| 	VideoSettings     videoSettings           `json:"videoSettings"` | 	VideoSettings     videoSettings           `json:"videoSettings"` | ||||||
|  | |||||||
| @ -22,6 +22,7 @@ const serverWelcomeMessageKey = "server_welcome_message" | |||||||
| const serverNameKey = "server_name" | const serverNameKey = "server_name" | ||||||
| const serverURLKey = "server_url" | const serverURLKey = "server_url" | ||||||
| const httpPortNumberKey = "http_port_number" | const httpPortNumberKey = "http_port_number" | ||||||
|  | const httpListenAddressKey = "http_listen_address" | ||||||
| const rtmpPortNumberKey = "rtmp_port_number" | const rtmpPortNumberKey = "rtmp_port_number" | ||||||
| const serverMetadataTagsKey = "server_metadata_tags" | const serverMetadataTagsKey = "server_metadata_tags" | ||||||
| const directoryEnabledKey = "directory_enabled" | const directoryEnabledKey = "directory_enabled" | ||||||
| @ -191,6 +192,21 @@ func SetHTTPPortNumber(port float64) error { | |||||||
| 	return _datastore.SetNumber(httpPortNumberKey, port) | 	return _datastore.SetNumber(httpPortNumberKey, port) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // GetHTTPListenAddress will return the HTTP listen address. | ||||||
|  | func GetHTTPListenAddress() string { | ||||||
|  | 	address, err := _datastore.GetString(httpListenAddressKey) | ||||||
|  | 	if err != nil { | ||||||
|  | 		log.Traceln(httpListenAddressKey, err) | ||||||
|  | 		return config.GetDefaults().WebServerIP | ||||||
|  | 	} | ||||||
|  | 	return string(address) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // SetHTTPListenAddress will set the server HTTP listen address. | ||||||
|  | func SetHTTPListenAddress(address string) error { | ||||||
|  | 	return _datastore.SetString(httpListenAddressKey, address) | ||||||
|  | } | ||||||
|  |  | ||||||
| // GetRTMPPortNumber will return the server RTMP port. | // GetRTMPPortNumber will return the server RTMP port. | ||||||
| func GetRTMPPortNumber() int { | func GetRTMPPortNumber() int { | ||||||
| 	port, err := _datastore.GetNumber(rtmpPortNumberKey) | 	port, err := _datastore.GetNumber(rtmpPortNumberKey) | ||||||
|  | |||||||
							
								
								
									
										9
									
								
								main.go
									
									
									
									
									
								
							
							
						
						
									
										9
									
								
								main.go
									
									
									
									
									
								
							| @ -41,6 +41,7 @@ func main() { | |||||||
| 	restoreDatabaseFile := flag.String("restoreDatabase", "", "Restore an Owncast database backup") | 	restoreDatabaseFile := flag.String("restoreDatabase", "", "Restore an Owncast database backup") | ||||||
| 	newStreamKey := flag.String("streamkey", "", "Set your stream key/admin password") | 	newStreamKey := flag.String("streamkey", "", "Set your stream key/admin password") | ||||||
| 	webServerPortOverride := flag.String("webserverport", "", "Force the web server to listen on a specific port") | 	webServerPortOverride := flag.String("webserverport", "", "Force the web server to listen on a specific port") | ||||||
|  | 	webServerIPOverride := flag.String("webserverip", "", "Force web server to listen on this IP address") | ||||||
| 	rtmpPortOverride := flag.Int("rtmpport", 0, "Set listen port for the RTMP server") | 	rtmpPortOverride := flag.Int("rtmpport", 0, "Set listen port for the RTMP server") | ||||||
|  |  | ||||||
| 	flag.Parse() | 	flag.Parse() | ||||||
| @ -117,9 +118,15 @@ func main() { | |||||||
| 		log.Println("Saving new web server port number to", portNumber) | 		log.Println("Saving new web server port number to", portNumber) | ||||||
| 		data.SetHTTPPortNumber(float64(portNumber)) | 		data.SetHTTPPortNumber(float64(portNumber)) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	config.WebServerPort = data.GetHTTPPortNumber() | 	config.WebServerPort = data.GetHTTPPortNumber() | ||||||
|  |  | ||||||
|  | 	// Set the web server ip | ||||||
|  | 	if *webServerIPOverride != "" { | ||||||
|  | 		log.Println("Saving new web server listen IP address to", *webServerIPOverride) | ||||||
|  | 		data.SetHTTPListenAddress(string(*webServerIPOverride)) | ||||||
|  | 	} | ||||||
|  | 	config.WebServerIP = data.GetHTTPListenAddress() | ||||||
|  |  | ||||||
| 	// Set the rtmp server port | 	// Set the rtmp server port | ||||||
| 	if *rtmpPortOverride > 0 { | 	if *rtmpPortOverride > 0 { | ||||||
| 		log.Println("Saving new RTMP server port number to", *rtmpPortOverride) | 		log.Println("Saving new RTMP server port number to", *rtmpPortOverride) | ||||||
|  | |||||||
| @ -2,6 +2,7 @@ package router | |||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	"fmt" | 	"fmt" | ||||||
|  | 	"net" | ||||||
| 	"net/http" | 	"net/http" | ||||||
|  |  | ||||||
| 	log "github.com/sirupsen/logrus" | 	log "github.com/sirupsen/logrus" | ||||||
| @ -172,6 +173,9 @@ func Start() error { | |||||||
| 	// Server http port | 	// Server http port | ||||||
| 	http.HandleFunc("/api/admin/config/webserverport", middleware.RequireAdminAuth(admin.SetWebServerPort)) | 	http.HandleFunc("/api/admin/config/webserverport", middleware.RequireAdminAuth(admin.SetWebServerPort)) | ||||||
|  |  | ||||||
|  | 	// Server http listen address | ||||||
|  | 	http.HandleFunc("/api/admin/config/webserverip", middleware.RequireAdminAuth(admin.SetWebServerIP)) | ||||||
|  |  | ||||||
| 	// Server rtmp port | 	// Server rtmp port | ||||||
| 	http.HandleFunc("/api/admin/config/rtmpserverport", middleware.RequireAdminAuth(admin.SetRTMPServerPort)) | 	http.HandleFunc("/api/admin/config/rtmpserverport", middleware.RequireAdminAuth(admin.SetRTMPServerPort)) | ||||||
|  |  | ||||||
| @ -206,9 +210,14 @@ func Start() error { | |||||||
| 	http.HandleFunc("/api/admin/config/customstyles", middleware.RequireAdminAuth(admin.SetCustomStyles)) | 	http.HandleFunc("/api/admin/config/customstyles", middleware.RequireAdminAuth(admin.SetCustomStyles)) | ||||||
|  |  | ||||||
| 	port := config.WebServerPort | 	port := config.WebServerPort | ||||||
|  | 	ip := config.WebServerIP | ||||||
|  |  | ||||||
| 	log.Infof("Web server is listening on port %d.", port) | 	ip_addr := net.ParseIP(ip) | ||||||
|  | 	if ip_addr == nil { | ||||||
|  | 		log.Fatalln("Invalid IP address", ip) | ||||||
|  | 	} | ||||||
|  | 	log.Infof("Web server is listening on IP %s port %d.", ip_addr.String(), port) | ||||||
| 	log.Infoln("The web admin interface is available at /admin.") | 	log.Infoln("The web admin interface is available at /admin.") | ||||||
|  |  | ||||||
| 	return http.ListenAndServe(fmt.Sprintf(":%d", port), nil) | 	return http.ListenAndServe(fmt.Sprintf("%s:%d", ip_addr.String(), port), nil) | ||||||
| } | } | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user
	 leuc
					leuc