Skip to content

Commit

Permalink
Merge branch 'ssr'
Browse files Browse the repository at this point in the history
  • Loading branch information
TimothyYe committed Jan 12, 2018
2 parents 9715ea1 + fbe4f0c commit c97ea37
Show file tree
Hide file tree
Showing 16 changed files with 468 additions and 222 deletions.
3 changes: 0 additions & 3 deletions conf/config-temp.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,6 @@ address = ":5000"
driver = "sqlite3"
connect = "./data/ignite.db"

[ss]
image = "goignite/ss-go:latest"

[host]
address = "localhost"
from = 5001
Expand Down
2 changes: 1 addition & 1 deletion controllers/index.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ func (router *MainRouter) SignupHandler(c *gin.Context) {
pwd := c.PostForm("password")
confirmPwd := c.PostForm("confirm-password")

matched, _ := regexp.MatchString("^[a-zA-Z0-9]+$", username)
matched, _ := regexp.MatchString("^[a-zA-Z0-9][a-zA-Z0-9_.-]+$", username)

if !matched {
fmt.Println("Username is invalid!")
Expand Down
98 changes: 74 additions & 24 deletions controllers/panel.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,27 @@ import (
"github.com/go-ignite/ignite/ss"
)

var (
servers = []string{"SS", "SSR"}
ssMethods = []string{"aes-256-cfb", "aes-128-gcm", "aes-192-gcm", "aes-256-gcm", "chacha20-ietf-poly1305"}
ssrMethods = []string{"aes-256-cfb", "aes-256-ctr", "chacha20", "chacha20-ietf"}
serverMethodsMap = map[string]map[string]bool{}
)

func init() {
ssMethodMap := map[string]bool{}
for _, method := range ssMethods {
ssMethodMap[method] = true
}
ssrMethodMap := map[string]bool{}
for _, method := range ssrMethods {
ssrMethodMap[method] = true
}

serverMethodsMap["SS"] = ssMethodMap
serverMethodsMap["SSR"] = ssrMethodMap
}

func (router *MainRouter) PanelIndexHandler(c *gin.Context) {
userID, exists := c.Get("userId")

Expand All @@ -32,16 +53,24 @@ func (router *MainRouter) PanelIndexHandler(c *gin.Context) {
}

uInfo := &models.UserInfo{
Id: user.Id,
Host: ss.Host,
Username: user.Username,
Status: user.Status,
PackageUsed: fmt.Sprintf("%.2f", user.PackageUsed),
PackageLimit: user.PackageLimit,
PackageLeft: fmt.Sprintf("%.2f", float32(user.PackageLimit)-user.PackageUsed),
ServicePort: user.ServicePort,
ServicePwd: user.ServicePwd,
Expired: user.Expired.Format("2006-01-02"),
Id: user.Id,
Host: ss.Host,
Username: user.Username,
Status: user.Status,
PackageUsed: fmt.Sprintf("%.2f", user.PackageUsed),
PackageLimit: user.PackageLimit,
PackageLeft: fmt.Sprintf("%.2f", float32(user.PackageLimit)-user.PackageUsed),
ServicePort: user.ServicePort,
ServicePwd: user.ServicePwd,
ServiceMethod: user.ServiceMethod,
ServiceType: user.ServiceType,
Expired: user.Expired.Format("2006-01-02"),
}
if uInfo.ServiceMethod == "" {
uInfo.ServiceMethod = "aes-256-cfb"
}
if uInfo.ServiceType == "" {
uInfo.ServiceType = "SS"
}

if user.PackageLimit == 0 {
Expand All @@ -51,7 +80,10 @@ func (router *MainRouter) PanelIndexHandler(c *gin.Context) {
}

c.HTML(http.StatusOK, "panel.html", gin.H{
"uInfo": uInfo,
"uInfo": uInfo,
"ss_methods": ssMethods,
"ssr_methods": ssrMethods,
"servers": servers,
})
}

Expand All @@ -65,26 +97,43 @@ func (router *MainRouter) LogoutHandler(c *gin.Context) {

func (router *MainRouter) CreateServiceHandler(c *gin.Context) {
userID, _ := c.Get("userId")
method := c.PostForm("method")
serverType := c.PostForm("server-type")

user := new(models.User)
router.db.Id(userID).Get(user)
fmt.Println("UserID", userID)
fmt.Println("ServerType:", serverType)
fmt.Println("Method:", method)

//Get all used ports.
var usedPorts []int
router.db.Table("user").Cols("service_port").Find(&usedPorts)
methodMap, ok := serverMethodsMap[serverType]
if !ok {
resp := models.Response{Success: false, Message: "服务类型配置错误!"}
c.JSON(http.StatusOK, resp)
return
}

if !methodMap[method] {
resp := models.Response{Success: false, Message: "加密方法配置错误!"}
c.JSON(http.StatusOK, resp)
return
}

user := new(models.User)
router.db.Id(userID).Get(user)
if user.ServiceId != "" {
resp := models.Response{Success: false, Message: "Service already created!"}
resp := models.Response{Success: false, Message: "服务已创建!"}
c.JSON(http.StatusOK, resp)
return
}

// 1. Create ss service
result, err := ss.CreateAndStartContainer(user.Username, &usedPorts)
//Get all used ports.
var usedPorts []int
router.db.Table("user").Cols("service_port").Find(&usedPorts)

// 1. Create ss service
result, err := ss.CreateAndStartContainer(serverType, user.Username, method, &usedPorts)
if err != nil {
log.Println("Create ss service error:", err.Error())
resp := models.Response{Success: false, Message: "Create service error!"}
resp := models.Response{Success: false, Message: "创建服务失败!"}
c.JSON(http.StatusOK, resp)
return
}
Expand All @@ -94,8 +143,9 @@ func (router *MainRouter) CreateServiceHandler(c *gin.Context) {
user.ServiceId = result.ID
user.ServicePort = result.Port
user.ServicePwd = result.Password
affected, err := router.db.Id(userID).Cols("status", "service_port", "service_pwd", "service_id").Update(user)

user.ServiceMethod = method
user.ServiceType = serverType
affected, err := router.db.Id(userID).Cols("status", "service_port", "service_pwd", "service_id", "service_method", "service_type").Update(user)
if affected == 0 || err != nil {
if err != nil {
log.Println("Update user info error:", err.Error())
Expand All @@ -104,14 +154,14 @@ func (router *MainRouter) CreateServiceHandler(c *gin.Context) {
//Force remove created container
ss.RemoveContainer(result.ID)

resp := models.Response{Success: false, Message: "Create service error!"}
resp := models.Response{Success: false, Message: "更新用户信息失败!"}
c.JSON(http.StatusOK, resp)
return
}

result.PackageLimit = user.PackageLimit
result.Host = ss.Host
resp := models.Response{Success: true, Message: "OK!", Data: result}
resp := models.Response{Success: true, Message: "服务创建成功!", Data: result}

c.JSON(http.StatusOK, resp)
}
8 changes: 5 additions & 3 deletions controllers/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ type MainRouter struct {

func (self *MainRouter) Initialize(r *gin.Engine) {
ss.Host = utils.HOST_Address
ss.ImageUrl = utils.SS_Image
ss.PortRange = []int{utils.HOST_From, utils.HOST_To}

//Init session store
Expand All @@ -39,8 +38,11 @@ func (self *MainRouter) Initialize(r *gin.Engine) {
}

go func() {
if err := ss.PullImage(); err != nil {
log.Printf("Pull image [%s] error: %s\n", ss.ImageUrl, err.Error())
if err := ss.PullImage(ss.SS_IMAGE); err != nil {
log.Printf("Pull image [%s] error: %s\n", ss.SS_IMAGE, err.Error())
}
if err := ss.PullImage(ss.SSR_IMAGE); err != nil {
log.Printf("Pull image [%s] error: %s\n", ss.SSR_IMAGE, err.Error())
}
}()
self.router.Run(utils.APP_Address)
Expand Down
4 changes: 4 additions & 0 deletions models/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@ type User struct {
PackageUsed float32 //Package bandwidth used, unit: GB
Status int `xorm:"default 0"` // 0=>not created 1=>running 2=>stopped
ServiceId string //SS container id
ServiceType string //SS container type
ServicePort int `xorm:"not null default 0"` //Docker service port for SS
ServicePwd string //Password for SS
ServiceMethod string //Encryption method for SS
LastStatsResult uint64 //Last time stats result,unit: byte
LastStatsTime *time.Time //Last time stats time
Created time.Time `xorm:"created"`
Expand All @@ -31,5 +33,7 @@ type UserInfo struct {
PackageLeftPercent string
ServicePort int
ServicePwd string
ServiceMethod string
ServiceType string
Expired string
}
38 changes: 26 additions & 12 deletions ss/ss.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,12 @@ import (
"github.com/go-ignite/ignite/utils"
)

const (
SS_IMAGE = "goignite/ss-libev:latest"
SSR_IMAGE = "goignite/ssr:latest"
)

var (
ImageUrl string
client *docker.Client
PortRange []int
Host string
Expand All @@ -28,8 +32,17 @@ func init() {
}
}

func CreateContainer(name string, usedPorts *[]int) (*models.ServiceResult, error) {
PullImage()
func CreateContainer(serverType, name, method string, usedPorts *[]int) (*models.ServiceResult, error) {
image := ""
switch serverType {
case "SS":
image = SS_IMAGE
case "SSR":
image = SSR_IMAGE
default:
return nil, errors.New("invalid server type")
}
PullImage(image)
password := utils.NewPasswd(16)
port, err := getAvailablePort(usedPorts)
if err != nil {
Expand All @@ -39,13 +52,14 @@ func CreateContainer(name string, usedPorts *[]int) (*models.ServiceResult, erro
container, err := client.CreateContainer(docker.CreateContainerOptions{
Name: name,
Config: &docker.Config{
Image: ImageUrl,
Cmd: []string{"-k", password, "-p", portStr},
ExposedPorts: map[docker.Port]struct{}{docker.Port(portStr + "/tcp"): {}},
Image: image,
Cmd: []string{"-k", password, "-m", method},
},
HostConfig: &docker.HostConfig{
PortBindings: map[docker.Port][]docker.PortBinding{
docker.Port(portStr + "/tcp"): {{HostPort: portStr}}},
docker.Port("3389/tcp"): {{HostPort: portStr}},
docker.Port("3389/udp"): {{HostPort: portStr}},
},
RestartPolicy: docker.AlwaysRestart(),
},
})
Expand All @@ -61,11 +75,11 @@ func CreateContainer(name string, usedPorts *[]int) (*models.ServiceResult, erro
}

func StartContainer(id string) error {
return client.StartContainer(id, nil)
return client.StartContainer(id, &docker.HostConfig{})
}

func PullImage() error {
return client.PullImage(docker.PullImageOptions{Repository: ImageUrl, OutputStream: os.Stdout},
func PullImage(image string) error {
return client.PullImage(docker.PullImageOptions{Repository: image, OutputStream: os.Stdout},
docker.AuthConfiguration{})
}

Expand Down Expand Up @@ -130,8 +144,8 @@ func GetContainerStatsOutNet(id string) (uint64, error) {
return stats.Networks["eth0"].TxBytes, nil
}

func CreateAndStartContainer(name string, usedPorts *[]int) (*models.ServiceResult, error) {
r, err := CreateContainer(name, usedPorts)
func CreateAndStartContainer(serverType, name, method string, usedPorts *[]int) (*models.ServiceResult, error) {
r, err := CreateContainer(serverType, name, method, usedPorts)
if err != nil {
return nil, err
}
Expand Down
79 changes: 79 additions & 0 deletions static/css/dropdown.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@

.big {
font-size: 1.2em;
}

.small {
font-size: .7em;
}

.square {
width: .7em;
height: .7em;
margin: .5em;
display: inline-block;
}

/* Custom dropdown */
.custom-dropdown {
position: relative;
display: inline-block;
vertical-align: middle;
margin: 10px; /* demo only */
}

.custom-dropdown select {
background-color: rgba(61, 201, 179, 1);
color: #fff;
font-size: inherit;
padding: .5em;
padding-right: 2.5em;
width: 245px;
border: 0;
margin: 0;
border-radius: 3px;
text-indent: 0.01px;
text-overflow: '';
-webkit-appearance: button; /* hide default arrow in chrome OSX */
}

.custom-dropdown::before,
.custom-dropdown::after {
content: "";
position: absolute;
pointer-events: none;
}

.custom-dropdown::after { /* Custom dropdown arrow */
content: "\25BC";
height: 1em;
font-size: .625em;
line-height: 1;
right: 1.2em;
top: 50%;
margin-top: -.5em;
}

.custom-dropdown::before { /* Custom dropdown arrow cover */
width: 2em;
right: 0;
top: 0;
bottom: 0;
border-radius: 0 3px 3px 0;
}

.custom-dropdown select[disabled] {
color: rgba(0,0,0,.3);
}

.custom-dropdown select[disabled]::after {
color: rgba(0,0,0,.1);
}

.custom-dropdown::before {
background-color: rgba(0,0,0,.15);
}

.custom-dropdown::after {
color: rgba(0,0,0,.4);
}
Loading

0 comments on commit c97ea37

Please sign in to comment.