diff --git a/CHANGELOG.md b/CHANGELOG.md index 9044cfc..81f1a7e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,10 +1,29 @@ # Change Log -## [v0.1.10](https://github.com/cad/ovpm/tree/v0.1.10) (2017-08-27) +## [v0.1.11](https://github.com/cad/ovpm/tree/v0.1.11) (2017-08-31) +[Full Changelog](https://github.com/cad/ovpm/compare/v0.1.10...v0.1.11) + +**Implemented enhancements:** + +- be able to change initial ip block [\#29](https://github.com/cad/ovpm/issues/29) + +**Fixed bugs:** + +- can add duplicate static ip [\#37](https://github.com/cad/ovpm/issues/37) +- net def --via flag doesn't work as documented [\#36](https://github.com/cad/ovpm/issues/36) +- Error when group 'nobody' doesn't exist [\#32](https://github.com/cad/ovpm/issues/32) +- --static option doesn't work when user update [\#28](https://github.com/cad/ovpm/issues/28) + +**Merged pull requests:** + +- openvpn user created by openvpn package, so use openvpn user instead. [\#35](https://github.com/cad/ovpm/pull/35) ([ilkerdagli](https://github.com/ilkerdagli)) + +## [v0.1.10](https://github.com/cad/ovpm/tree/v0.1.10) (2017-08-29) [Full Changelog](https://github.com/cad/ovpm/compare/v0.1.9...v0.1.10) **Implemented enhancements:** +- command line flags for tcp or udp at initialize [\#30](https://github.com/cad/ovpm/issues/30) - show network types in cli [\#27](https://github.com/cad/ovpm/issues/27) ## [v0.1.9](https://github.com/cad/ovpm/tree/v0.1.9) (2017-08-27) @@ -76,4 +95,3 @@ - implement remote control proto [\#8](https://github.com/cad/ovpm/issues/8) - write docs [\#4](https://github.com/cad/ovpm/issues/4) - write unit tests [\#3](https://github.com/cad/ovpm/issues/3) - diff --git a/README.md b/README.md index e6c36fc..ea7fc50 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,18 @@ $ sudo yum-config-manager --add-repo https://cad.github.io/ovpm/rpm/ovpm.repo $ sudo yum install ovpm ``` +**from DEB (Ubuntu/DEBIAN):** + +This is tested only on Ubuntu >=16.04.3 LTS + +```bash +# Add APT Repo +$ sudo sh -c 'echo "deb [trusted=yes] https://cad.github.io/ovpm/deb/ ovpm main" >> /etc/apt/sources.list' + +# Install OVPM +$ sudo yum install ovpm +``` + **from Source (go get):** Only dependency for ovpm is **OpenVPN>=2.3**. diff --git a/api/rpc.go b/api/rpc.go index be4ba43..e9485e6 100644 --- a/api/rpc.go +++ b/api/rpc.go @@ -76,7 +76,10 @@ func (s *UserService) Update(ctx context.Context, req *pb.UserUpdateRequest) (*p } - user.Update(req.Password, noGW, req.HostID) + err = user.Update(req.Password, noGW, req.HostID) + if err != nil { + return nil, err + } pbUser := pb.UserResponse_User{ Username: user.GetUsername(), ServerSerialNumber: user.GetServerSerialNumber(), @@ -184,7 +187,8 @@ func (s *VPNService) Init(ctx context.Context, req *pb.VPNInitRequest) (*pb.VPNI case pb.VPNProto_NOPREF: proto = ovpm.UDPProto } - if err := ovpm.Init(req.Hostname, req.Port, proto); err != nil { + + if err := ovpm.Init(req.Hostname, req.Port, proto, req.IPBlock); err != nil { logrus.Errorf("server can not be created: %v", err) } return &pb.VPNInitResponse{}, nil diff --git a/bindata/bindata.go b/bindata/bindata.go index 04f7b96..01b25f5 100644 --- a/bindata/bindata.go +++ b/bindata/bindata.go @@ -152,7 +152,7 @@ func templateIptablesTmpl() (*asset, error) { return a, nil } -var _templateServerConfTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x94\x7a\x6d\x6f\xdb\xb8\xb2\xff\x7b\x7d\x8a\x81\xfd\xa2\x09\x60\x2b\x8e\xdb\xee\x69\x37\xff\xff\xbd\xf0\x3a\xee\xd6\xd8\xd6\xf5\x6d\x9c\x7d\x00\xf6\x0d\x2d\x8d\x2d\xc2\x12\xa9\x25\x29\xbb\x3e\x07\xe7\xbb\x5f\xcc\x90\x94\xe4\x24\xdd\x8b\xb3\x8b\xa0\xb6\x44\x0e\xe7\x79\x7e\x33\xf4\x5d\xad\x8d\x83\xdb\xdb\xf7\x6f\x12\xfe\xf4\xaf\x7f\x41\xba\xa6\x0f\xff\xfe\x77\x92\x0c\x61\x33\x5f\x83\x36\xf0\x78\xbf\x06\x8b\xe6\x88\xe6\xbf\x93\xbb\xda\x68\xa7\xc1\x65\x75\xe2\x3f\xf1\x16\xfe\xe4\xf7\x0c\x72\x3c\x82\x6b\xd4\x00\x4e\xb2\x2c\x21\x33\x28\x1c\x82\x00\xa3\x1b\x87\x39\x2c\xd7\xf4\x52\x61\x39\x6a\xd7\x8a\xfa\xc9\x5a\x05\xe8\x0a\x34\x0a\x5d\x58\x9b\x26\x43\x78\xb4\xd8\xae\x9f\x0c\x40\xee\xe0\xac\x1b\x10\x06\xbb\xc5\x5b\x23\xf3\xbd\x54\xfb\x64\x08\x42\xe5\x50\x88\x23\x42\x6d\xd0\x93\xcd\x41\xf0\x56\x38\x4a\xe3\x1a\x51\x82\x54\x0e\xcd\x4e\x64\x18\x96\xf3\x6e\xcc\x41\x3a\x38\x49\x57\x10\x79\xd3\xd1\x6e\x57\x13\x2f\x4b\x7f\xf8\x49\x28\x07\x4e\x43\xa6\x95\x33\xba\x04\x91\x65\x68\x2d\xd4\xba\x94\x99\x44\x9b\x0c\x41\x1f\xd1\x80\x2b\x10\x7e\x5d\xaf\x46\xbc\xa7\x6a\xac\x8b\x82\xee\xa4\xc1\x93\x28\xcb\x64\x08\xa6\x29\xd1\xc2\x4e\xfb\xd5\xf4\xb7\x79\x5c\xdd\x6c\x66\xeb\xcb\x83\xbf\x28\x50\x5a\x8d\x7f\x93\x2a\xd7\x27\x0b\xf6\x6c\x1d\x56\xd6\x53\xce\x84\x82\xbd\x3c\x7a\x71\x00\xbf\xd5\xc4\x85\x83\x46\x49\x07\xaa\xa9\xb6\x68\x46\x60\x9b\xac\x00\x61\x49\xad\x93\x40\x2f\xd0\x1a\x41\x13\x14\x3c\x56\x3a\xc7\x41\xe0\x45\xda\xb0\xac\xd2\xd6\x75\xe7\x05\x91\xbc\xd9\x94\x76\xb0\x6b\x54\xe6\xa4\x56\xc9\x10\x1a\x55\x92\x16\x88\xa5\x5a\x18\x27\x45\x59\x9e\xc9\x8b\x76\x0d\x7d\xc8\xa5\x15\xdb\x92\x98\x24\x1a\x51\x03\xad\xe4\x2f\x48\x7d\x17\x8c\x9e\x04\xc7\x22\x27\x8b\x0a\x50\x88\xb9\xf5\x1b\x67\x6b\x52\xcb\xeb\x29\x88\x5c\xd4\x0e\x0d\x28\x51\xd1\x31\x3b\xa3\x2b\x5e\xb1\x42\x77\xd2\xe6\x00\x73\xad\x14\x32\xb3\x16\x6a\xa1\xb0\x0c\xbe\x94\x0c\xbd\xc7\x54\xda\x90\x05\x84\x02\xad\x30\x05\x12\xfe\xf7\x35\x3c\xac\xa7\x24\x44\x21\xf7\x05\x1a\xf2\x5d\x36\xa6\x38\x33\x0b\xe4\x04\x16\x4b\xa2\x7a\xc4\x4e\x48\x3a\xb6\xc7\xec\x73\x61\x67\xeb\xc8\x2d\x69\x79\xf5\xdc\xb2\xd0\xd8\x86\xf5\x97\x6b\xf5\xca\x85\xb3\xd8\x28\x77\xd1\x52\xf0\xf9\xbc\x11\x35\x29\xe5\xe1\xe1\xd3\xcd\xe6\xd3\x03\x18\xad\x1d\x64\x68\x9c\xdc\xc9\x8c\xfc\xec\x2a\x13\xd7\xa3\xfe\x93\x64\x08\x57\xf4\xf5\x7a\xc4\x9e\x5f\x1b\x79\xa4\x75\x07\x3c\xc3\xd5\x01\xcf\xd7\x29\xc0\x42\x64\x05\x64\xa5\x44\xe5\x42\x7c\x10\xc7\x3e\x0b\x78\x27\x66\x65\xb9\x02\xa5\x01\x7d\x52\x4c\x9e\xd6\x25\x43\xa6\xb3\x93\x25\x29\x6f\xd3\x6d\x22\x1a\x24\xbd\x27\x6a\xd9\x77\xc8\x5d\xac\xf7\x77\x2b\x2a\x84\x4c\xf8\x8d\xc9\x90\xe4\x41\xff\x66\x80\xc2\x9e\xc7\xc6\x8a\x01\xe4\xd2\x60\xe6\xb4\x39\xb3\x0e\x05\x91\x0e\x81\xb6\x03\x9b\x19\x59\x3b\x1f\x44\x7b\x54\x68\x84\x93\x6a\x0f\x5f\x1f\x66\x7d\xd1\x6d\x90\xa6\x27\xb3\x4d\x01\xbe\x62\x85\x14\x22\x64\xc9\xc6\x72\x0c\x51\xe4\xfc\xd5\x20\xcc\x75\x55\x69\x05\x2b\xe2\x2f\x5a\xce\x8b\x14\x48\x21\xa9\x4a\xef\xf8\x85\x17\xee\xe2\x40\x2f\xcc\x4c\x9d\xe1\xf7\xb7\x93\xf7\xac\x9c\x4a\x28\xb1\xc7\x8a\x56\x7a\x43\x73\xf0\x6e\x91\x8e\xce\x39\xe0\x6a\x54\x14\x5f\xf4\x58\x94\x96\x79\x02\x01\xeb\x5f\xe6\x0f\x30\xbc\x9d\x12\x1f\x95\x70\x94\xd4\xa2\xae\xc9\xa4\x16\x11\x06\xf5\x21\xb3\xb7\xd3\xa8\x2a\x79\x44\x90\x8a\x0e\x84\x5a\xec\xf1\x3a\x4d\xee\x32\x01\x51\xa1\x37\x24\xfd\x4d\x26\xd2\xcc\xb8\xe4\x8e\x2d\x78\xf9\xca\xcb\xe9\x5f\xd3\x49\x2f\xbe\xa5\x17\x30\x84\x4d\x21\x2d\xb3\x02\xb6\xd0\x4d\x99\x93\x3c\x07\xac\x1d\x58\xca\xc0\x2e\x49\x32\xc1\xc5\x62\x3e\x9b\xa3\x71\x6b\xe1\x0a\xaa\x18\x7c\x28\x3f\xee\x3d\x24\x8a\xf4\xec\x17\x3c\xc7\x47\xc9\x10\xee\xe5\x6e\x27\x11\x0a\x2c\x4b\x2f\x8f\x11\x15\x3a\x34\x9c\xa2\x7e\xf6\x16\x47\x9f\xb6\xc9\x21\x29\x89\xff\x98\x0c\x01\x40\xd7\xa8\xac\x2d\x21\x2f\x78\x0f\x8c\x75\xe3\x20\x2f\x6e\x27\xd3\x37\x69\x8d\x15\xd0\x07\xf2\xb7\x66\x6b\x9d\x74\x8d\x43\x98\x4e\xde\xbc\x63\x63\xd3\xab\x7e\xad\x69\xac\xaf\x2f\xbc\x60\x2b\x9d\xf7\x9f\x64\x98\x17\x3d\x82\xc9\x5d\x5e\x3c\x51\x55\x5e\xd0\x0e\x7e\x99\x17\x2c\xdb\xfd\xc7\x35\x31\x63\x7b\x02\xc6\x0c\xe5\x74\xad\x4b\xbd\x3f\x13\x4f\xad\x2a\x6d\xb3\xa5\x3a\x74\x25\xf2\xdc\xa0\x25\x36\xe0\x28\x05\x2c\xd7\xd7\x5d\xce\x8d\xd9\x23\x86\xd8\x71\x9a\x4e\xd2\xf7\xec\xa4\xa5\x3e\xa1\x09\x31\xab\x93\xa1\xa7\x58\x53\xd1\xc7\x1c\xae\x5c\x81\x0a\x14\xba\xd7\x93\x11\xc8\x14\x53\x10\x70\xf3\x7a\x02\x35\x9a\x40\x8b\x0e\xb9\xc7\x9d\x68\x4a\x67\x29\x46\x78\x2d\x5c\x51\xea\x37\x98\xe9\xaa\x42\x95\x63\x7e\x9d\x44\xd6\x03\xbb\x24\xd5\x5c\xab\x9d\xdc\x37\xa6\xcb\x1e\x94\xb5\x88\x27\x62\xa0\x3c\x83\xe0\x52\x12\x36\x0c\x59\xed\xd1\xff\x9d\x86\xdc\x88\x53\x0c\xab\x20\x3b\x55\x4a\xa3\x2b\x32\x7b\x2f\xbf\x70\x2d\x72\xe2\x80\x70\x3b\x49\xdf\xa5\x93\xf4\x96\x49\x49\x67\xb1\xdc\x8d\x42\xc1\x31\x68\x9d\x5f\xb9\x45\xa8\x04\x31\x72\x14\xb2\xf4\xd9\x5a\x47\xc5\x11\xe5\x5e\x02\x6c\x37\xc4\x65\x86\x43\xfe\x22\x11\x68\xd5\x1e\x9b\x72\xca\xa0\x7d\x94\xaa\xa1\x94\x0a\x81\x3c\xae\x73\xa3\x64\xf8\x1c\xb4\xa4\x6d\xbe\x8b\xc1\xca\xec\x73\x35\x92\x6a\xa7\xd3\xe4\x2e\x08\x1a\xce\x99\xc0\xf4\xed\xdb\x34\xfe\x4d\x92\xf0\x96\x7c\x6b\x85\x84\xe0\xf8\xe3\x67\x61\x0f\xc1\xbd\x3e\x0b\xa9\x9c\x90\x8a\xc0\x18\x66\xda\xe4\x94\xb4\x82\x84\xff\x6f\xfc\x5f\x2d\x30\x5a\xae\xa3\xa2\x29\xc1\x59\xab\x33\x29\x7c\xb9\x94\xca\x8b\x14\x92\xfb\x72\xd7\x1a\x6a\xaf\xd1\x42\x4e\x61\xa7\x49\x1b\xd2\xb2\xa6\x05\x79\xd7\x88\x4f\xf3\x35\x57\xed\x5b\xdf\x0c\x19\x4f\x58\x2b\xf7\x0a\xf3\x60\x1f\xae\x02\xcf\x19\xe9\xaa\x78\xad\x75\x49\xd5\xd9\xc1\x49\x10\x7f\xb5\xc1\xa3\xd4\x8d\x25\x3f\x0a\xa4\xd2\x44\xee\x32\x76\xba\x31\xad\x1e\xd7\x68\xac\xb4\x0e\x64\x5d\xa7\xee\xdb\xdf\xf8\x24\xe9\xfb\xb9\x5d\x92\x21\xfc\x11\x81\xdb\x4e\x1a\xeb\x38\x19\x73\x9a\xf9\xf2\xf0\xca\xb6\x0b\x21\x13\xb5\xd8\xca\x52\x3a\x0a\x5c\xa7\x03\xa0\x6c\x2b\x7d\x0b\x69\x3c\xbc\xa4\xc7\xf1\x30\x8a\xfd\xe5\xbc\x07\x7a\xb8\x70\xaa\x0e\x30\x56\x42\x79\x1c\x60\x09\x13\x33\xaa\x58\xae\x6f\x14\xba\x8a\xcc\xab\x15\x53\x0b\xe7\xb5\x54\x46\x50\xa0\x41\x38\xa1\x37\x63\x53\xb5\x91\xf1\xe6\xe6\xc2\x75\x52\x80\x0f\x52\x31\x7d\x5e\xcc\x47\xd2\x49\xc2\x4a\x0e\x55\xb2\x84\x11\x8a\x89\x7b\x0f\x68\xa3\xf5\x8a\xad\xfc\xff\x03\xe1\xb7\x13\x40\x95\xc7\x6f\xb7\x93\xc9\x35\x29\x42\x94\xa5\x0e\xb0\xc3\xa3\xe5\x27\xbe\x90\x02\x7c\x42\x8f\x26\x62\xbc\xf8\x94\xe2\xd8\x2f\x28\x76\x7a\xa0\xf2\x45\xc8\xdf\x46\xc7\x38\x68\x21\x4a\x7a\x19\x24\xd0\xf1\xd9\xf1\xf8\x1f\x3a\x04\x63\x16\xe2\x5e\xc0\xfd\xc7\xf9\x7a\x5c\x1b\xfd\xed\x3c\x82\x13\x2b\x3b\x7a\xb7\x13\xe5\xc1\x8b\x4b\x96\x89\x51\x12\x58\x64\xad\xd2\xde\x2e\x7d\x70\x52\xc9\x50\xb6\x90\xaa\xe7\xfb\x41\x7d\x1e\x5d\x53\xde\xbc\x5f\x3d\xb4\xa0\x2a\x66\xc4\x14\x5e\xf0\x52\x0f\x53\xbf\xef\xa7\xcf\xbd\x94\x62\xf7\xfb\x7e\xfa\xc4\x4b\x19\xb3\x3a\xfc\xd1\xdb\x8d\x35\xa6\x15\x39\x91\x36\x07\x4b\x5e\x19\xb5\x71\x15\xfa\x8e\x0e\x0c\x5f\x47\x85\x75\xa0\xc9\xab\xa5\x87\x89\x41\xd2\x86\xad\x6e\x14\x03\x6c\xaf\xee\xb0\xf8\xa9\xbd\xc9\x86\xeb\xc6\x16\xbe\xcd\xb4\x51\xf1\x21\xbb\x05\x1f\x3c\x81\x74\x51\xd7\x8c\xd9\x48\xac\x16\x09\x7a\x97\xb6\xb0\xc5\x42\xaa\x36\x1f\x79\x88\xd3\x07\x88\x94\x7b\x5c\x81\xac\xdd\xa7\x7b\xb9\x50\x30\x60\x23\xa8\xee\xcf\x3a\x28\x7d\xe2\x33\x89\xb3\x0b\x77\xe8\xe0\x75\xb0\x34\x27\xb7\xab\x98\xdf\x2f\x83\x94\x2a\xf0\x56\x64\x87\x97\x7d\x2a\x4d\x86\x9e\xfe\xed\xfb\x69\x7a\xfb\xc3\xbb\xf4\xfd\xb3\x02\x11\x3d\x7e\xfa\x6c\xe9\xed\xf7\x96\xbe\x7d\xb6\x74\xfa\xbd\xa5\xaf\x9f\x2d\x7d\xfd\xbd\xa5\x6f\x92\x61\x4d\xa6\x1a\x84\x0d\xff\xa0\x0d\x14\x88\x4f\x37\x0c\x9e\x2c\x0c\x94\x7f\x78\x69\x21\x6c\x74\x28\x00\x60\x6b\xcc\x08\x7c\xf7\x62\xc8\x7b\x44\x7c\x91\x0c\x5b\xcf\x24\x80\xb0\x03\xf1\x3c\x29\x41\x21\x2c\x88\x68\xe0\x64\x18\xf1\x97\xf7\x0e\x90\xce\x3b\x42\x80\xba\x6c\x72\x06\x57\x64\x12\x3f\x07\x18\xf5\x9b\x9b\x66\xdb\xb5\x2e\x83\x2c\xcb\x7d\x7f\x1d\x1d\xbf\xc7\x57\xc8\x43\x1c\xee\x5c\x67\xad\xc7\xf5\x2f\x83\x82\xeb\x94\x1c\x7f\xf1\xfb\xec\xf3\xfa\xd3\xe2\x47\x78\x20\x44\x67\xfb\x41\xe5\x9b\x5a\x12\x8b\x9f\xf5\x9a\xc2\xcc\xb7\x35\xd4\x25\xc3\x60\x53\x60\xa9\x15\xd5\x51\x52\x65\x90\x86\xe4\xb7\x15\xb5\x6c\x97\xb2\x53\xb0\x77\xfa\xa2\x7a\x21\xb2\x42\x2a\xec\xc6\x0b\xd1\x52\x6f\x26\xe9\xed\xf4\xdd\x85\x1f\x4f\xdf\xbc\xa3\xbc\xf1\x81\x52\xd4\x08\x1a\x15\x12\x3d\x27\x79\x8e\x2a\xce\xff\xf6\xc7\x64\x18\x94\x13\x2a\x79\x2e\x0d\x64\x59\xfe\x7f\xbb\xb9\x07\x85\xaa\x1b\x3c\x71\x4b\x92\x65\xf9\x4d\x27\x64\xcc\x6c\xa1\xda\xf8\x2e\x41\x5e\x52\xf6\xbc\xc3\x13\xde\x93\xd0\xe7\x84\x40\xa7\x9c\xd2\x91\x7d\xf5\x24\x1f\x78\xa4\x1d\xa6\x42\x61\x64\xc2\xa5\x5d\x5a\xc0\x6f\xa2\xaa\x4b\xf4\x84\xda\xac\x49\xe9\xb7\x6b\x36\x88\x21\xa9\xf6\x23\x9e\xb0\xc4\xf4\x1d\x00\x7a\x87\x24\x7d\x31\xea\xc6\x6e\x54\x21\x06\x3e\x2b\xf4\xba\x40\xfb\xb2\xa7\xf4\xc7\x58\x61\x78\xd4\x53\x13\x29\xef\x1b\xe6\xec\xd4\xbd\x82\xa4\x77\x14\xca\xef\x19\xeb\x46\x5b\xfe\x9d\x29\xef\x5e\x36\xe5\xf3\xa7\xdc\x07\xce\xef\x63\x4b\x14\x2c\x29\xf2\xbc\x87\x0c\x08\x41\x5c\x18\x33\x58\xaf\x85\x7c\x94\x31\x22\x7b\xf1\xc3\x34\x49\x32\x53\x8e\x8f\x68\xe4\xce\xb7\x96\xf3\xaf\x9f\xba\x63\xba\xb8\x11\xee\x42\x25\xa8\x18\xf2\xe7\x72\xb7\x43\xe3\xc3\xa9\x9d\xe2\x3c\x99\xf6\x71\x60\xb6\x0b\x61\x6f\x74\x53\x87\xc9\x44\x07\x73\x36\x5c\xf3\xc8\xb6\xee\xa4\xa1\x42\x57\xe8\x9c\x05\xb8\xba\xbd\x86\xaf\x8d\x82\xaa\x29\x9d\x24\xbf\x88\xe9\x3d\x17\x58\x69\x65\x47\xa0\x55\xc0\x23\x22\x2b\x58\x62\xf0\x67\xf8\x11\x4e\xcb\xd5\x8b\x43\xb4\xb0\x3e\x6e\xf7\x1b\x6f\x3c\x69\x10\x75\x6d\x74\x6d\xa4\x70\x58\x9e\xc9\x9e\x57\xd3\x6b\xb8\x9a\xe5\x47\xa1\x32\xcc\xaf\x61\x1e\x03\xc9\x0f\x58\xb8\x27\x3b\x2b\x51\xc9\x8c\x10\x63\x20\x5d\xe9\x9c\x34\x7b\x31\xd3\x93\x8a\x9a\x80\x5a\x2b\xcb\x56\xf3\xfa\x8a\xac\x10\x9e\xef\xb4\xd5\x69\xe8\xc1\xe7\xba\xb0\xec\x79\xc6\x23\x58\x51\xa2\x30\x6a\x1c\xbd\xd1\xb3\x95\x26\x77\x97\x8f\xd3\x1b\xff\x22\xf1\xf3\x5a\x6f\xc9\x7c\xe4\x3d\xa9\x1b\x8e\xf8\xc1\x73\x44\x7f\x9c\xfc\xba\x11\x15\x23\x05\xbf\x36\xc0\xb2\xdc\xf7\xc0\xc9\x90\x3a\x60\x6e\xd6\xf7\xc2\xe1\x49\x90\xe8\x46\x37\xfb\xa2\x9b\xf6\x66\x22\x0e\x0b\x88\xe4\x72\x0d\xce\x88\x1d\x95\xa5\x98\x25\x4f\xb8\x85\xad\xd1\x27\x0f\x26\x19\x72\x44\x74\x57\x6a\x7d\x68\x6a\x66\x60\xaf\x9f\x92\x26\x13\x6d\x9e\x21\x80\x98\x85\x2f\x86\x92\xab\xd9\x86\x5c\xd0\x5c\xa0\xbc\xa7\xde\x11\x11\x05\x3f\xf0\xa8\x5e\x52\x1f\x97\xa3\x69\xa7\xc0\xb4\x86\xc5\x25\x5f\x41\x53\x9e\xaf\xd3\xe4\x2e\x14\xe7\xa0\xa1\x71\xd4\x44\x8e\xbb\x5b\xd8\x9e\x6b\x61\xed\x38\x2f\xb2\x7a\xf0\x1f\xac\x24\x28\x8e\x86\xbb\xd4\x80\x14\xdb\xea\xd8\x6a\xdc\xa2\xa3\xb4\x48\xae\x14\x9a\x48\x22\xef\x05\x0e\x96\xeb\x4a\xd1\xfd\xea\xc1\x6b\xe0\xb7\xe5\xcb\xa8\x79\x3e\xfb\x75\x31\xdb\x50\x0c\x16\xce\xd5\x3f\xde\xdc\xe8\x1a\xd5\xb1\x56\xa9\x42\x77\xb3\x13\x7f\xa5\x85\xab\xca\x21\x71\x97\x89\x23\x0a\x67\xc3\xd4\xa1\x43\x16\x5b\xa4\x32\x60\x70\xe7\xc7\x87\xdc\xa5\x36\xdb\x92\xeb\x79\x07\xd5\x2d\xa9\xee\x28\x73\xcc\x61\x7b\xe6\x91\x54\xae\x6c\x9a\xe9\xaa\x55\x24\x9d\x31\xd6\x35\x57\x7e\xda\x37\x9d\xbc\x4b\x7f\xf8\x47\x3a\x9d\x4e\xe9\x6f\x90\xbc\xbc\xea\x5d\xca\xff\xb3\xea\x1e\xdb\x1c\xfc\xc4\xcb\x5b\x00\xdc\xcf\x64\x3d\x2f\xef\xcd\x36\x06\x16\x71\x00\x1d\x3e\xa6\x8c\xf0\xd3\x39\x3a\xfe\xe8\x62\x7c\xeb\x0b\x97\x0d\x73\x8b\x16\x89\x12\x16\xdb\x69\x93\x61\xff\x88\x17\x96\x8e\xc2\xd8\xfd\x12\x35\x33\xb3\xfd\x9c\x74\x91\xdc\x08\x89\xf1\xe6\x57\xf6\xa5\xcb\x82\x50\x53\x9c\x1e\x07\xfc\xf3\x77\x5a\x91\xbb\x2e\xdf\x06\x4e\x09\xcd\xc8\x7d\xe1\x22\xc0\xe9\x7a\x20\x3f\x9f\xee\x00\xd4\xcd\x01\xcf\x5c\x0e\x08\xa2\x11\x96\xeb\xf0\x94\x8d\x45\x9e\xc7\x20\xed\x74\x8c\xa7\x44\xa5\x1f\x5d\x3b\xb4\x0c\x36\xeb\xc6\x50\xe5\xa1\x1d\x1f\x34\xf5\x22\x3a\x6f\xf8\x6e\x82\xa0\x23\x21\x48\xec\x8d\xa1\x02\xd8\x64\x9c\x29\x09\xbc\x86\xb1\xfb\x25\x47\xb5\x90\xc6\xcf\x9c\x97\x1f\xe0\x8f\x2f\x8f\xf0\x71\xf6\xeb\x02\x56\x5f\x36\xf0\xf3\x62\xb5\xf8\x3a\xdb\x2c\xee\x61\xb9\xba\x5f\xfe\xba\xbc\x7f\x9c\x7d\xa2\x80\x5b\x7c\xdd\x2c\x3f\x2c\xe7\xb3\xcd\xe2\xe6\x97\xc5\x1f\xb0\x9e\x2d\xbf\x3e\xc0\x87\x2f\x5f\x61\x31\x9b\x7f\x84\xf9\xa7\xe5\x62\xb5\x21\x5e\xf8\xeb\xc7\xd9\xaf\xcb\xd5\xcf\xb0\xdc\x3c\xc0\x97\xdf\x56\xf0\xb8\x5a\xfe\xcf\xe3\x02\x06\xf3\x2f\x9f\x3f\x7f\x59\xc1\x6a\xf6\x79\x31\xa0\xb5\x8f\x2b\x7a\xb2\x58\x6d\x60\xf3\x71\xf9\x00\x9f\x96\xab\x05\x7c\x79\xdc\xa4\xc9\x5d\xde\xd4\x25\xf3\x3b\xce\xf8\x2e\x87\x82\xe9\x80\x58\x8b\x92\x6c\xd2\x59\x87\xf2\x27\x5a\xa8\xa5\xda\x8f\x4b\x79\xe0\xc1\x04\x5a\x2b\xf6\x18\x5d\xd6\x92\x52\xb8\x27\xe2\x12\xa8\x8d\x2b\xf8\xc6\x2d\xf4\x6e\xa5\x54\x07\xb0\xda\x57\x75\xd6\x23\x77\x98\xd4\x8f\x59\xea\x3e\x55\x58\xe7\xdb\x40\x7e\x47\xa0\x77\x4f\x95\x36\xd7\x27\x45\x9e\xbc\x26\x23\xe1\x11\xcd\x19\x6e\x27\x60\x31\xd3\x2a\xb7\xa3\x38\x4e\x61\xca\x06\x2b\xcd\x1d\x42\x8d\xdc\xb3\xfa\x31\x98\xdc\x81\xd2\xcc\x7c\x6c\xec\x73\xc8\x1b\x13\x0a\x02\xdc\x4e\x23\x35\x70\xb2\x42\xa8\xd1\x48\x9d\xa7\x49\xa7\x88\xdb\x09\x2d\x22\x05\x91\x63\xe0\x37\x67\x04\xed\x68\x0c\xf5\xed\x5b\x3c\xf3\x56\x3a\x3f\xa6\x15\xea\x0f\xcf\xf1\x12\x68\xd4\xbb\x4c\x1d\x7c\xfc\x3c\x9b\xb7\x41\x34\xf0\x5d\x69\x81\x65\x0d\xdb\x52\x67\x07\xb8\xd7\x0f\x20\x9c\x13\xd9\xc1\xb2\x22\x1f\xef\xd7\xc0\xb7\xc1\xbb\x52\xeb\xdc\x8f\xc0\xfa\x13\xf6\xcb\xc1\xfa\xb1\x56\x30\x1e\xef\x51\x1d\xf0\x0c\xe3\xb1\x1f\xf6\x83\x13\x29\x7b\xe3\xe5\x88\xb6\xbd\x2d\x09\x0e\xdd\xde\x23\xb1\x4e\x32\x5d\x9f\xfd\x3d\x8a\xb4\x70\xc0\x73\x37\xdf\x65\x3d\xb5\xf3\xfe\xde\xfd\xc2\xab\xc9\x2b\x3f\x7b\x75\x97\x87\xbc\xba\x7d\x15\x9f\xb6\x23\xdd\x3b\x57\xda\xb1\x68\x28\x9c\x99\x39\x98\x5c\x5c\x5a\x48\xdb\x5e\x54\x0c\xe1\x81\x2f\xf3\x88\x27\x73\xae\x9d\xde\x1b\x51\x17\x32\x83\x4c\xd6\x21\x23\x6e\x42\x13\xb4\x93\x7b\x90\x0e\x2b\x2f\xca\x96\xda\xaa\x5a\x72\x0e\x0b\xce\x15\x2f\x84\xfc\x52\x3e\x89\x4b\x7f\x59\xa6\xc9\x9d\xa7\x07\x3f\x7d\x18\xcf\x7f\x9a\x43\xf8\x6f\x08\x3f\x95\xfa\xb4\x93\xb6\x80\xab\x90\x75\xaf\xdb\xa5\xb3\xc5\xc3\xf8\x76\xfa\x2e\xac\x1f\xd2\xf7\xf6\xdd\xfd\xe2\x61\xbc\xb8\x5f\xbc\xf6\x2f\x87\xb0\x31\x94\xd9\xc6\xf7\x8b\x07\x86\xfe\x1e\xca\x66\xba\xaa\xf9\xfe\x40\xab\xa8\x21\xc2\x10\x14\x2b\xbd\x9b\xed\x80\x7b\xa5\xe3\x11\x62\xef\xe6\x9a\xb2\x34\x65\xa5\xf6\xbd\x54\xdf\x11\x33\x4d\xe8\xa8\x71\xf9\x4f\x1d\x83\xbc\x12\xdf\x64\xd5\x54\xe1\x32\x9a\x81\xb1\x56\x59\x63\xa8\x1c\x95\xe7\x98\x71\xd9\x91\xdb\x22\x83\x2d\x14\xe7\xfa\x95\x26\x77\x95\xf8\x36\x8e\xaf\xc3\xf0\x6e\xe9\x5e\x51\xaf\xb2\xd7\x3a\x07\x99\xa3\x08\xb8\xad\xc9\x2e\xc6\x2d\xc9\x30\x80\xe9\x57\x96\xfb\x34\x59\x22\xa5\x12\xb1\xe3\x51\x93\x92\x4e\x8a\x52\xfe\x93\x1b\x6f\xef\xf0\x7f\x84\x4b\xf5\xe6\xb2\x7e\x50\x7b\xc3\xa3\xb8\x17\x6e\xe2\xd3\xa4\xb1\x68\x40\xe9\xad\xce\xcf\x09\xc3\xec\xf8\x25\x28\x21\x0e\xa3\x7d\x05\x0f\x65\xd4\x19\x1e\xc5\x89\xa3\x96\x79\xdb\x31\xf2\x2c\x22\x60\x21\x83\x56\x37\x26\x43\x9e\xaa\x85\xc9\x3a\x3b\x98\x70\x1e\xef\x69\x28\xb5\xda\xa3\xe1\x4a\xee\xb7\x93\x81\xb6\xc8\x59\xd4\xb7\x21\x0c\x4c\xa2\xe0\x9c\xa5\xf6\x46\xe4\x98\x26\x81\xa7\x31\x45\x6c\xfc\x1c\x2e\xda\xbf\x34\xae\x6e\x28\x10\x6c\x41\x19\xc1\x3a\xe1\x9a\xee\x96\xef\xe4\xd3\x59\xb0\x61\x3b\x14\xe0\x7e\xc5\x99\x46\x51\x96\x8f\xb0\xd6\xe0\xc9\x48\xe7\x50\x85\x74\x5a\x49\xd5\x38\x4c\x93\x40\x32\xa4\x92\xb1\xff\x9a\x96\x7a\x9f\x3c\x01\x1e\xa5\xde\x77\x05\x80\xd5\x46\xd0\xd8\xe3\x2d\x7b\xb6\xf4\xfa\x4a\x87\xab\x98\xf6\x47\x0d\x72\x07\xa6\x51\x8a\x11\xb6\xf5\x17\xc6\x47\x99\x21\xff\x82\xe1\xdc\xa3\x12\xa2\x75\xf0\xe7\xda\x50\xb4\x57\xf0\x81\xea\xfa\x9f\xc1\x75\xfe\x2c\xf5\xbe\x77\xf9\x7c\x1d\x7f\x8f\x42\x67\x6a\x43\xff\x8c\x45\x4d\x88\x8e\x81\xce\x11\x8d\xa1\x62\xe2\xd1\x86\x67\x9f\x76\x0c\x98\x4a\x30\xb8\x57\x8e\xaf\x53\x3a\x24\x06\xad\x3a\x4c\x4f\x16\x6e\x6a\xaa\xa4\xa7\x82\xde\x0d\xba\x43\x02\x8d\xee\x44\xe9\x52\x60\x7e\xb4\x42\x0f\x76\xbb\xb2\x76\xb5\x6d\x9c\x9f\x1f\x68\x57\x10\x68\xa7\xd3\xe2\x7f\x11\xea\x92\xb6\xef\x7a\x52\x5c\xbc\xe0\x74\xc8\xfd\x4f\x1f\x96\x41\x89\x47\x2c\xc9\xad\x68\x8d\xc7\x41\x70\x44\xb3\xd5\x56\xba\xb3\x0f\xa0\x09\x27\x55\x59\xa2\x72\x23\xc0\x6f\x19\xd6\x8e\xc1\xcf\x4e\x38\x51\x02\x1a\xa3\x0d\x01\xae\x37\x1e\x27\x09\xab\x7d\x56\xe9\x2e\xf0\x4b\x68\xc8\xdc\xc9\x10\xde\xb2\x0f\xfd\xc0\xf1\xc8\xa5\x8b\xba\x50\xdc\x36\xfb\x9e\xd3\x51\x25\xdc\x96\x58\x11\xcd\xf7\xc0\x33\x16\x67\xb0\x22\x04\xe9\x19\xc3\x84\xfe\x85\xd7\x2c\x12\xb1\x95\x21\x18\xac\xd1\xff\x50\x20\xfa\x56\x0a\x30\x73\xfe\xf7\x2e\xd3\x09\xc3\xcd\xbf\x1a\x54\x94\x1d\x3a\xf7\x0b\xd1\xc4\x98\x30\x3c\xe4\x6e\xc4\xe1\x5e\x9b\x73\x7b\x5f\xa8\x7d\xf4\x04\x27\x2d\xf5\x9e\xf2\x97\xbf\x5f\x4e\xfe\x37\x00\x00\xff\xff\x56\x29\xd3\x95\x7b\x25\x00\x00") +var _templateServerConfTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x94\x7a\x6d\x6f\xdb\xb8\xb2\xff\x7b\x7d\x8a\x81\xfd\xa2\x09\x60\x2b\x8e\xdb\xee\x69\x37\xff\xff\xbd\xf0\x3a\xee\xd6\xd8\xd6\xf5\x6d\x9c\x7d\x00\xf6\x0d\x2d\x8d\x2d\xc2\x12\xa9\x25\x29\xbb\x3e\x07\xe7\xbb\x5f\xcc\x90\x94\xe4\x24\xdd\x8b\xb3\x8b\xa0\xb6\x44\x0e\xe7\x79\x7e\x33\xf4\x5d\xad\x8d\x83\xdb\xdb\xf7\x6f\x12\xfe\xf4\xaf\x7f\x41\xba\xa6\x0f\xff\xfe\x77\x92\x0c\x61\x33\x5f\x83\x36\xf0\x78\xbf\x06\x8b\xe6\x88\xe6\xbf\x93\xbb\xda\x68\xa7\xc1\x65\x75\xe2\x3f\xf1\x16\xfe\xe4\xf7\x0c\x72\x3c\x82\x6b\xd4\x00\x4e\xb2\x2c\x21\x33\x28\x1c\x82\x00\xa3\x1b\x87\x39\x2c\xd7\xf4\x52\x61\x39\x6a\xd7\x8a\xfa\xc9\x5a\x05\xe8\x0a\x34\x0a\x5d\x58\x9b\x26\x43\x78\xb4\xd8\xae\x9f\x0c\x40\xee\xe0\xac\x1b\x10\x06\xbb\xc5\x5b\x23\xf3\xbd\x54\xfb\x64\x08\x42\xe5\x50\x88\x23\x42\x6d\xd0\x93\xcd\x41\xf0\x56\x38\x4a\xe3\x1a\x51\x82\x54\x0e\xcd\x4e\x64\x18\x96\xf3\x6e\xcc\x41\x3a\x38\x49\x57\x10\x79\xd3\xd1\x6e\x57\x13\x2f\x4b\x7f\xf8\x49\x28\x07\x4e\x43\xa6\x95\x33\xba\x04\x91\x65\x68\x2d\xd4\xba\x94\x99\x44\x9b\x0c\x41\x1f\xd1\x80\x2b\x10\x7e\x5d\xaf\x46\xbc\xa7\x6a\xac\x8b\x82\xee\xa4\xc1\x93\x28\xcb\x64\x08\xa6\x29\xd1\xc2\x4e\xfb\xd5\xf4\xb7\x79\x5c\xdd\x6c\x66\xeb\xcb\x83\xbf\x28\x50\x5a\x8d\x7f\x93\x2a\xd7\x27\x0b\xf6\x6c\x1d\x56\xd6\x53\xce\x84\x82\xbd\x3c\x7a\x71\x00\xbf\xd5\xc4\x85\x83\x46\x49\x07\xaa\xa9\xb6\x68\x46\x60\x9b\xac\x00\x61\x49\xad\x93\x40\x2f\xd0\x1a\x41\x13\x14\x3c\x56\x3a\xc7\x41\xe0\x45\xda\xb0\xac\xd2\xd6\x75\xe7\x05\x91\xbc\xd9\x94\x76\xb0\x6b\x54\xe6\xa4\x56\xc9\x10\x1a\x55\x92\x16\x88\xa5\x5a\x18\x27\x45\x59\x9e\xc9\x8b\x76\x0d\x7d\xc8\xa5\x15\xdb\x92\x98\x24\x1a\x51\x03\xad\xe4\x2f\x48\x7d\x17\x8c\x9e\x04\xc7\x22\x27\x8b\x0a\x50\x88\xb9\xf5\x1b\x67\x6b\x52\xcb\xeb\x29\x88\x5c\xd4\x0e\x0d\x28\x51\xd1\x31\x3b\xa3\x2b\x5e\xb1\x42\x77\xd2\xe6\x00\x73\xad\x14\x32\xb3\x16\x6a\xa1\xb0\x0c\xbe\x94\x0c\xbd\xc7\x54\xda\x90\x05\x84\x02\xad\x30\x05\x12\xfe\xf7\x35\x3c\xac\xa7\x24\x44\x21\xf7\x05\x1a\xf2\x5d\x36\xa6\x38\x33\x0b\xe4\x04\x16\x4b\xa2\x7a\xc4\x4e\x48\x3a\xb6\xc7\xec\x73\x61\x67\xeb\xc8\x2d\x69\x79\xf5\xdc\xb2\xd0\xd8\x86\xf5\x97\x6b\xf5\xca\x85\xb3\xd8\x28\x77\xd1\x52\xf0\xf9\xbc\x11\x35\x29\xe5\xe1\xe1\xd3\xcd\xe6\xd3\x03\x18\xad\x1d\x64\x68\x9c\xdc\xc9\x8c\xfc\xec\x2a\x13\xd7\xa3\xfe\x93\x64\x08\x57\xf4\xf5\x7a\xc4\x9e\x5f\x1b\x79\xa4\x75\x07\x3c\xc3\xd5\x01\xcf\xd7\x29\xc0\x42\x64\x05\x64\xa5\x44\xe5\x42\x7c\x10\xc7\x3e\x0b\x78\x27\x66\x65\xb9\x02\xa5\x01\x7d\x52\x4c\x9e\xd6\x25\x43\xa6\xb3\x93\x25\x29\x6f\xd3\x6d\x22\x1a\x24\xbd\x27\x6a\xd9\x77\xc8\x5d\xac\xf7\x77\x2b\x2a\x84\x4c\xf8\x8d\xc9\x90\xe4\x41\xff\x66\x80\xc2\x9e\xc7\xc6\x8a\x01\xe4\xd2\x60\xe6\xb4\x39\xb3\x0e\x05\x91\x0e\x81\xb6\x03\x9b\x19\x59\x3b\x1f\x44\x7b\x54\x68\x84\x93\x6a\x0f\x5f\x1f\x66\x7d\xd1\x6d\x90\xa6\x27\xb3\x4d\x01\xbe\x62\x85\x14\x22\x64\xc9\xc6\x72\x0c\x51\xe4\xfc\xd5\x20\xcc\x75\x55\x69\x05\x2b\xe2\x2f\x5a\xce\x8b\x14\x48\x21\xa9\x4a\xef\xf8\x85\x17\xee\xe2\x40\x2f\xcc\x4c\x9d\xe1\xf7\xb7\x93\xf7\xac\x9c\x4a\x28\xb1\xc7\x8a\x56\x7a\x43\x73\xf0\x6e\x91\x8e\xce\x39\xe0\x6a\x54\x14\x5f\xf4\x58\x94\x96\x79\x02\x01\xeb\x5f\xe6\x0f\x30\xbc\x9d\x12\x1f\x95\x70\x94\xd4\xa2\xae\xc9\xa4\x16\x11\x06\xf5\x21\xb3\xb7\xd3\xa8\x2a\x79\x44\x90\x8a\x0e\x84\x5a\xec\xf1\x3a\x4d\xee\x32\x01\x51\xa1\x37\x24\xfd\x4d\x26\xd2\xcc\xb8\xe4\x8e\x2d\x78\xf9\xca\xcb\xe9\x5f\xd3\x49\x2f\xbe\xa5\x17\x30\x84\x4d\x21\x2d\xb3\x02\xb6\xd0\x4d\x99\x93\x3c\x07\xac\x1d\x58\xca\xc0\x2e\x49\x32\xc1\xc5\x62\x3e\x9b\xa3\x71\x6b\xe1\x0a\xaa\x18\x7c\x28\x3f\xee\x3d\x24\x8a\xf4\xec\x17\x3c\xc7\x47\xc9\x10\xee\xe5\x6e\x27\x11\x0a\x2c\x4b\x2f\x8f\x11\x15\x3a\x34\x9c\xa2\x7e\xf6\x16\x47\x9f\xb6\xc9\x21\x29\x89\xff\x98\x0c\x01\x40\xd7\xa8\xac\x2d\x21\x2f\x78\x0f\x8c\x75\xe3\x20\x2f\x6e\x27\xd3\x37\x69\x8d\x15\xd0\x07\xf2\xb7\x66\x6b\x9d\x74\x8d\x43\x98\x4e\xde\xbc\x63\x63\xd3\xab\x7e\xad\x69\xac\xaf\x2f\xbc\x60\x2b\x9d\xf7\x9f\x64\x98\x17\x3d\x82\xc9\x5d\x5e\x3c\x51\x55\x5e\xd0\x0e\x7e\x99\x17\x2c\xdb\xfd\xc7\x35\x31\x63\x7b\x02\xc6\x0c\xe5\x74\xad\x4b\xbd\x3f\x13\x4f\xad\x2a\x6d\xb3\xa5\x3a\x74\x25\xf2\xdc\xa0\x25\x36\xe0\x28\x05\x2c\xd7\xd7\x5d\xce\x8d\xd9\x23\x86\xd8\x71\x9a\x4e\xd2\xf7\xec\xa4\xa5\x3e\xa1\x09\x31\xab\x93\xa1\xa7\x58\x53\xd1\xc7\x1c\xae\x5c\x81\x0a\x14\xba\xd7\x93\x11\xc8\x14\x53\x10\x70\xf3\x7a\x02\x35\x9a\x40\x8b\x0e\xb9\xc7\x9d\x68\x4a\x67\x29\x46\x78\x2d\x5c\x51\xea\x37\x98\xe9\xaa\x42\x95\x63\x7e\x9d\x44\xd6\x03\xbb\x24\xd5\x5c\xab\x9d\xdc\x37\xa6\xcb\x1e\x94\xb5\x88\x27\x62\xa0\x3c\x83\xe0\x52\x12\x36\x0c\x59\xed\xd1\xff\x9d\x86\xdc\x88\x53\x0c\xab\x20\x3b\x55\x4a\xa3\x2b\x32\x7b\x2f\xbf\x70\x2d\x72\xe2\x80\x70\x3b\x49\xdf\xa5\x93\xf4\x96\x49\x49\x67\xb1\xdc\x8d\x42\xc1\x31\x68\x9d\x5f\xb9\x45\xa8\x04\x31\x72\x14\xb2\xf4\xd9\x5a\x47\xc5\x11\xe5\x5e\x02\x6c\x37\xc4\x65\x86\x43\xfe\x22\x11\x68\xd5\x1e\x9b\x72\xca\xa0\x7d\x94\xaa\xa1\x94\x0a\x81\x3c\xae\x73\xa3\x64\xf8\x1c\xb4\xa4\x6d\xbe\x8b\xc1\xca\xec\x73\x35\x92\x6a\xa7\xd3\xe4\x2e\x08\x1a\xce\x99\xc0\xf4\xed\xdb\x34\xfe\x4d\x92\xf0\x96\x7c\x6b\x85\x84\xe0\xf8\xe3\x67\x61\x0f\xc1\xbd\x3e\x0b\xa9\x9c\x90\x8a\xc0\x18\x66\xda\xe4\x94\xb4\x82\x84\xff\x6f\xfc\x5f\x2d\x30\x5a\xae\xa3\xa2\x29\xc1\x59\xab\x33\x29\x7c\xb9\x94\xca\x8b\x14\x92\xfb\x72\xd7\x1a\x6a\xaf\xd1\x42\x4e\x61\xa7\x49\x1b\xd2\xb2\xa6\x05\x79\xd7\x88\x4f\xf3\x35\x57\xed\x5b\xdf\x0c\x19\x4f\x58\x2b\xf7\x0a\xf3\x60\x1f\xae\x02\xcf\x19\xe9\xaa\x78\xad\x75\x49\xd5\xd9\xc1\x49\x10\x7f\xb5\xc1\xa3\xd4\x8d\x25\x3f\x0a\xa4\xd2\x44\xee\x32\x76\xba\x31\xad\x1e\xd7\x68\xac\xb4\x0e\x64\x5d\xa7\xee\xdb\xdf\xf8\x24\xe9\xfb\xb9\x5d\x92\x21\xfc\x11\x81\xdb\x4e\x1a\xeb\x38\x19\x73\x9a\xf9\xf2\xf0\xca\xb6\x0b\x21\x13\xb5\xd8\xca\x52\x3a\x0a\x5c\xa7\x03\xa0\x6c\x2b\x7d\x0b\x69\x3c\xbc\xa4\xc7\xf1\x30\x8a\xfd\xe5\xbc\x07\x7a\xb8\x70\xaa\x0e\x30\x56\x42\x79\x1c\x60\x09\x13\x33\xaa\x58\xae\x6f\x14\xba\x8a\xcc\xab\x15\x53\x0b\xe7\xb5\x54\x46\x50\xa0\x41\x38\xa1\x37\x63\x53\xb5\x91\xf1\xe6\xe6\xc2\x75\x52\x80\x0f\x52\x31\x7d\x5e\xcc\x47\xd2\x49\xc2\x4a\x0e\x55\xb2\x84\x11\x8a\x89\x7b\x0f\x68\xa3\xf5\x8a\xad\xfc\xff\x03\xe1\xb7\x13\x40\x95\xc7\x6f\xb7\x93\xc9\x35\x29\x42\x94\xa5\x0e\xb0\xc3\xa3\xe5\x27\xbe\x90\x02\x7c\x42\x8f\x26\x62\xbc\xf8\x94\xe2\xd8\x2f\x28\x76\x7a\xa0\xf2\x45\xc8\xdf\x46\xc7\x38\x68\x21\x4a\x7a\x19\x24\xd0\xf1\xd9\xf1\xf8\x1f\x3a\x04\x63\x16\xe2\x5e\xc0\xfd\xc7\xf9\x7a\x5c\x1b\xfd\xed\x3c\x82\x13\x2b\x3b\x7a\xb7\x13\xe5\xc1\x8b\x4b\x96\x89\x51\x12\x58\x64\xad\xd2\xde\x2e\x7d\x70\x52\xc9\x50\xb6\x90\xaa\xe7\xfb\x41\x7d\x1e\x5d\x53\xde\xbc\x5f\x3d\xb4\xa0\x2a\x66\xc4\x14\x5e\xf0\x52\x0f\x53\xbf\xef\xa7\xcf\xbd\x94\x62\xf7\xfb\x7e\xfa\xc4\x4b\x19\xb3\x3a\xfc\xd1\xdb\x8d\x35\xa6\x15\x39\x91\x36\x07\x4b\x5e\x19\xb5\x71\x15\xfa\x8e\x0e\x0c\x5f\x47\x85\x75\xa0\xc9\xab\xa5\x87\x89\x41\xd2\x86\xad\x6e\x14\x03\x6c\xaf\xee\xb0\xf8\xa9\xbd\xc9\x86\xeb\xc6\x16\xbe\xcd\xb4\x51\xf1\x21\xbb\x05\x1f\x3c\x81\x74\x51\xd7\x8c\xd9\x48\xac\x16\x09\x7a\x97\xb6\xb0\xc5\x42\xaa\x36\x1f\x79\x88\xd3\x07\x88\x94\x7b\x5c\x81\xac\xdd\xa7\x7b\xb9\x50\x30\x60\x23\xa8\xee\xcf\x3a\x28\x7d\xe2\x33\x89\xb3\x0b\x77\xe8\xe0\x75\xb0\x34\x27\xb7\xab\x98\xdf\x2f\x83\x94\x2a\xf0\x56\x64\x87\x97\x7d\x2a\x4d\x86\x9e\xfe\xed\xfb\x69\x7a\xfb\xc3\xbb\xf4\xfd\xb3\x02\x11\x3d\x7e\xfa\x6c\xe9\xed\xf7\x96\xbe\x7d\xb6\x74\xfa\xbd\xa5\xaf\x9f\x2d\x7d\xfd\xbd\xa5\x6f\x92\x61\x4d\xa6\x1a\x84\x0d\xff\xa0\x0d\x14\x88\x4f\x37\x0c\x9e\x2c\x0c\x94\x7f\x78\x69\x21\x6c\x74\x28\x00\x60\x6b\xcc\x08\x7c\xf7\x62\xc8\x7b\x44\x7c\x91\x0c\x5b\xcf\x24\x80\xb0\x03\xf1\x3c\x29\x41\x21\x2c\x88\x68\xe0\x64\x18\xf1\x97\xf7\x0e\x90\xce\x3b\x42\x80\xba\x6c\x72\x06\x57\x64\x12\x3f\x07\x18\xf5\x9b\x9b\x66\xdb\xb5\x2e\x83\x2c\xcb\x7d\x7f\x1d\x1d\xbf\xc7\x57\xc8\x43\x1c\xee\x5c\x67\xad\xc7\xf5\x2f\x83\x82\xeb\x94\x1c\x7f\xf1\xfb\xec\xf3\xfa\xd3\xe2\x47\x78\x20\x44\x67\xfb\x41\xe5\x9b\x5a\x12\x8b\x9f\xf5\x9a\xc2\xcc\xb7\x35\xd4\x25\xc3\x60\x53\x60\xa9\x15\xd5\x51\x52\x65\x90\x86\xe4\xb7\x15\xb5\x6c\x97\xb2\x53\xb0\x77\xfa\xa2\x7a\x21\xb2\x42\x2a\xec\xc6\x0b\xd1\x52\x6f\x26\xe9\xed\xf4\xdd\x85\x1f\x4f\xdf\xbc\xa3\xbc\xf1\x81\x52\xd4\x08\x1a\x15\x12\x3d\x27\x79\x8e\x2a\xce\xff\xf6\xc7\x64\x18\x94\x13\x2a\x79\x2e\x0d\x64\x59\xfe\x7f\xbb\xb9\x07\x85\xaa\x1b\x3c\x71\x4b\x92\x65\xf9\x4d\x27\x64\xcc\x6c\xa1\xda\xf8\x2e\x41\x5e\x52\xf6\xbc\xc3\x13\xde\x93\xd0\xe7\x84\x40\xa7\x9c\xd2\x91\x7d\xf5\x24\x1f\x78\xa4\x1d\xa6\x42\x61\x64\xc2\xa5\x5d\x5a\xc0\x6f\xa2\xaa\x4b\xf4\x84\xda\xac\x49\xe9\xb7\x6b\x36\x88\x21\xa9\xf6\x23\x9e\xb0\xc4\xf4\x1d\x00\x7a\x87\x24\x7d\x31\xea\xc6\x6e\x54\x21\x06\x3e\x2b\xf4\xba\x40\xfb\xb2\xa7\xf4\xc7\x58\x61\x78\xd4\x53\x13\x29\xef\x1b\xe6\xec\xd4\xbd\x82\xa4\x77\x14\xca\xef\x19\xeb\x46\x5b\xfe\x9d\x29\xef\x5e\x36\xe5\xf3\xa7\xdc\x07\xce\xef\x63\x4b\x14\x2c\x29\xf2\xbc\x87\x0c\x08\x41\x5c\x18\x33\x58\xaf\x85\x7c\x94\x31\x22\x7b\xf1\xc3\x34\x49\x32\x53\x8e\x8f\x68\xe4\xce\xb7\x96\xf3\xaf\x9f\xba\x63\xba\xb8\x11\xee\x42\x25\xa8\x18\xf2\xe7\x72\xb7\x43\xe3\xc3\xa9\x9d\xe2\x3c\x99\xf6\x71\x60\xb6\x0b\x61\x6f\x74\x53\x87\xc9\x44\x07\x73\x36\x5c\xf3\xc8\xb6\xee\xa4\xa1\x42\x57\xe8\x9c\x05\xb8\xba\xbd\x86\xaf\x8d\x82\xaa\x29\x9d\x24\xbf\x88\xe9\x3d\x17\x58\x69\x65\x47\xa0\x55\xc0\x23\x22\x2b\x58\x62\xf0\x67\xf8\x11\x4e\xcb\xd5\x8b\x43\xb4\xb0\x3e\x6e\xf7\x1b\x6f\x3c\x69\x10\x75\x6d\x74\x6d\xa4\x70\x58\x9e\xc9\x9e\x57\xd3\x6b\xb8\x9a\xe5\x47\xa1\x32\xcc\xaf\x61\x1e\x03\xc9\x0f\x58\xb8\x27\x3b\x2b\x51\xc9\x8c\x10\x63\x20\x5d\xe9\x9c\x34\x7b\x31\xd3\x93\x8a\x9a\x80\x5a\x2b\xcb\x56\xf3\xfa\x8a\xac\x10\x9e\xef\xb4\xd5\x69\xe8\xc1\xe7\xba\xb0\xec\x79\xc6\x23\x58\x51\xa2\x30\x6a\x1c\xbd\xd1\xb3\x95\x26\x77\x97\x8f\xd3\x1b\xff\x22\xf1\xf3\x5a\x6f\xc9\x7c\xe4\x3d\xa9\x1b\x8e\xf8\xc1\x73\x44\x7f\x9c\xfc\xba\x11\x15\x23\x05\xbf\x36\xc0\xb2\xdc\xf7\xc0\xc9\x90\x3a\x60\x6e\xd6\xf7\xc2\xe1\x49\x90\xe8\x46\x37\xfb\xa2\x9b\xf6\x66\x22\x0e\x0b\x88\xe4\x72\x0d\xce\x88\x1d\x95\xa5\x98\x25\x4f\xb8\x85\xad\xd1\x27\x0f\x26\x19\x72\x44\x74\x57\x6a\x7d\x68\x6a\x66\x60\xaf\x9f\x92\x26\x13\x6d\x9e\x21\x80\x98\x85\x2f\x86\x92\xab\xd9\x86\x5c\xd0\x5c\xa0\xbc\xa7\xde\x11\x11\x05\x3f\xf0\xa8\x5e\x52\x1f\x97\xa3\x69\xa7\xc0\xb4\x86\xc5\x25\x5f\x41\x53\x9e\xaf\xd3\xe4\x2e\x14\xe7\xa0\xa1\x71\xd4\x44\x8e\xbb\x5b\xd8\x9e\x6b\x61\xed\x38\x2f\xb2\x7a\xf0\x1f\xac\x24\x28\x8e\x86\xbb\xd4\x80\x14\xdb\xea\xd8\x6a\xdc\xa2\xa3\xb4\x48\xae\x14\x9a\x48\x22\xef\x05\x0e\x96\xeb\x4a\xd1\xfd\xea\xc1\x6b\xe0\xb7\xe5\xcb\xa8\x79\x3e\xfb\x75\x31\xdb\x50\x0c\x16\xce\xd5\x3f\xde\xdc\xe8\x1a\xd5\xb1\x56\xa9\x42\x77\xb3\x13\x7f\xa5\x85\xab\xca\x21\x71\x97\x89\x23\x0a\x67\xc3\xd4\xa1\x43\x16\x5b\xa4\x32\x60\x70\xe7\xc7\x87\xdc\xa5\x36\xdb\x92\xeb\x79\x07\xd5\x2d\xa9\xee\x28\x73\xcc\x61\x7b\xe6\x91\x54\xae\x6c\x9a\xe9\xaa\x55\x24\x9d\x31\xd6\x35\x57\x7e\xda\x37\x9d\xbc\x4b\x7f\xf8\x47\x3a\x9d\x4e\xe9\x6f\x90\xbc\xbc\xea\x5d\xca\xff\xb3\xea\x1e\xdb\x1c\xfc\xc4\xcb\x5b\x00\xdc\xcf\x64\x3d\x2f\xef\xcd\x36\x06\x16\x71\x00\x1d\x3e\xa6\x8c\xf0\xd3\x39\x3a\xfe\xe8\x62\x7c\xeb\x0b\x97\x0d\x73\x8b\x16\x89\x12\x16\xdb\x69\x93\x61\xff\x88\x17\x96\x8e\xc2\xd8\xfd\x12\x35\x33\xb3\xfd\x9c\x74\x91\xdc\x08\x89\xf1\xe6\x57\xf6\xa5\xcb\x82\x50\x53\x9c\x1e\x07\xfc\xf3\x77\x5a\x91\xbb\x2e\xdf\x06\x4e\x09\xcd\xc8\x7d\xe1\x22\xc0\xe9\x7a\x20\x3f\x9f\xee\x00\xd4\xcd\x01\xcf\x5c\x0e\x08\xa2\x11\x96\xeb\xf0\x94\x8d\x45\x9e\xc7\x20\xed\x74\x8c\xa7\x44\xa5\x1f\x5d\x3b\xb4\x0c\x36\xeb\xc6\x50\xe5\xa1\x1d\x1f\x34\xf5\x22\x3a\x6f\xf8\x6e\x82\xa0\x23\x21\x48\xec\x8d\xa1\x02\xd8\x64\x9c\x29\x09\xbc\x86\xb1\xfb\x25\x47\xb5\x90\xc6\xcf\x9c\x97\x1f\xe0\x8f\x2f\x8f\xf0\x71\xf6\xeb\x02\x56\x5f\x36\xf0\xf3\x62\xb5\xf8\x3a\xdb\x2c\xee\x61\xb9\xba\x5f\xfe\xba\xbc\x7f\x9c\x7d\xa2\x80\x5b\x7c\xdd\x2c\x3f\x2c\xe7\xb3\xcd\xe2\xe6\x97\xc5\x1f\xb0\x9e\x2d\xbf\x3e\xc0\x87\x2f\x5f\x61\x31\x9b\x7f\x84\xf9\xa7\xe5\x62\xb5\x21\x5e\xf8\xeb\xc7\xd9\xaf\xcb\xd5\xcf\xb0\xdc\x3c\xc0\x97\xdf\x56\xf0\xb8\x5a\xfe\xcf\xe3\x02\x06\xf3\x2f\x9f\x3f\x7f\x59\xc1\x6a\xf6\x79\x31\xa0\xb5\x8f\x2b\x7a\xb2\x58\x6d\x60\xf3\x71\xf9\x00\x9f\x96\xab\x05\x7c\x79\xdc\xa4\xc9\x5d\xde\xd4\x25\xf3\x3b\xce\xf8\x2e\x87\x82\xe9\x80\x58\x8b\x92\x6c\xd2\x59\x87\xf2\x27\x5a\xa8\xa5\xda\x8f\x4b\x79\xe0\xc1\x04\x5a\x2b\xf6\x18\x5d\xd6\x92\x52\xb8\x27\xe2\x12\xa8\x8d\x2b\xf8\xc6\x2d\xf4\x6e\xa5\x54\x07\xb0\xda\x57\x75\xd6\x23\x77\x98\xd4\x8f\x59\xea\x3e\x55\x58\xe7\xdb\x40\x7e\x47\xa0\x77\x4f\x95\x36\xd7\x27\x45\x9e\xbc\x26\x23\xe1\x11\xcd\x19\x6e\x27\x60\x31\xd3\x2a\xb7\xa3\x38\x4e\x61\xca\x06\x2b\xcd\x1d\x42\x8d\xdc\xb3\xfa\x31\x98\xdc\x81\xd2\xcc\x7c\x6c\xec\x73\xc8\x1b\x13\x0a\x02\xdc\x4e\x23\x35\x70\xb2\x42\xa8\xd1\x48\x9d\xa7\x49\xa7\x88\xdb\x09\x2d\x22\x05\x91\x63\xe0\x37\x67\x04\xed\x68\x0c\xf5\xed\x5b\x3c\xf3\x56\x3a\x3f\xa6\x15\xea\x0f\xcf\xf1\x12\x68\xd4\xbb\x4c\x1d\x7c\xfc\x3c\x9b\xb7\x41\x34\xf0\x5d\x69\x81\x65\x0d\xdb\x52\x67\x07\xb8\xd7\x0f\x20\x9c\x13\xd9\xc1\xb2\x22\x1f\xef\xd7\xc0\xb7\xc1\xbb\x52\xeb\xdc\x8f\xc0\xfa\x13\xf6\xcb\xc1\xfa\xb1\x56\x30\x1e\xef\x51\x1d\xf0\x0c\xe3\xb1\x1f\xf6\x83\x13\x29\x7b\xe3\xe5\x88\xb6\xbd\x2d\x09\x0e\xdd\xde\x23\xb1\x4e\x32\x5d\x9f\xfd\x3d\x8a\xb4\x70\xc0\x73\x37\xdf\x65\x3d\xb5\xf3\xfe\xde\xfd\xc2\xab\xc9\x2b\x3f\x7b\x75\x97\x87\xbc\xba\x7d\x15\x9f\xb6\x23\xdd\x3b\x57\xda\xb1\x68\x28\x9c\x99\x39\x98\x5c\x5c\x5a\x48\xdb\x5e\x54\x0c\xe1\x81\x2f\xf3\x88\x27\x73\xae\x9d\xde\x1b\x51\x17\x32\x83\x4c\xd6\x21\x23\x6e\x42\x13\xb4\x93\x7b\x90\x0e\x2b\x2f\xca\x96\xda\xaa\x5a\x72\x0e\x0b\xce\x15\x2f\x84\xfc\x52\x3e\x89\x4b\x7f\x59\xa6\xc9\x9d\xa7\x07\x3f\x7d\x18\xcf\x7f\x9a\x43\xf8\x6f\x08\x3f\x95\xfa\xb4\x93\xb6\x80\xab\x90\x75\xaf\xdb\xa5\xb3\xc5\xc3\xf8\x76\xfa\x2e\xac\x1f\xd2\xf7\xf6\xdd\xfd\xe2\x61\xbc\xb8\x5f\xbc\xf6\x2f\x87\xb0\x31\x94\xd9\xc6\xf7\x8b\x07\x86\xfe\x1e\xca\x66\xba\xaa\xf9\xfe\x40\xab\xa8\x21\xc2\x10\x14\x2b\xbd\x9b\xed\x80\x7b\xa5\xe3\x11\x62\xef\xe6\x9a\xb2\x34\x65\xa5\xf6\xbd\x54\xdf\x11\x33\x4d\xe8\xa8\x71\xf9\x4f\x1d\x83\xbc\x12\xdf\x64\xd5\x54\xe1\x32\x9a\x81\xb1\x56\x59\x63\xa8\x1c\x95\xe7\x98\x71\xd9\x91\xdb\x22\x83\x2d\x14\xe7\xfa\x95\x26\x77\x95\xf8\x36\x8e\xaf\xc3\xf0\x6e\xe9\x5e\x51\xaf\xb2\xd7\x3a\x07\x99\xa3\x08\xb8\xad\xc9\x2e\xc6\x2d\xc9\x30\x80\xe9\x57\x96\xfb\x34\x59\x22\xa5\x12\xb1\xe3\x51\x93\x92\x4e\x8a\x52\xfe\x93\x1b\x6f\xef\xf0\x7f\x84\x4b\xf5\xe6\xb2\x7e\x50\x7b\xc3\xa3\xb8\x17\x6e\xe2\xd3\xa4\xb1\x24\x9a\x8f\x8b\x84\x71\x76\xfb\x2d\xa8\x21\x8e\xa3\x7d\x0d\x0f\x85\xd4\x19\x1e\xc6\x89\xa3\x96\x79\xdb\x33\xf2\x34\x22\xa0\x21\x83\x56\x37\x26\x43\x9e\xab\x85\xd9\x3a\xbb\x98\x70\x1e\xf1\x69\x28\xb5\xda\xa3\xe1\x5a\xee\xb7\x93\x89\xb6\xc8\x79\xd4\x37\x22\x0c\x4d\xa2\xe8\x9c\xa7\xf6\x46\xe4\x98\x26\x81\xa7\x31\xc5\x6c\xfc\x1c\xae\xda\xbf\x34\xae\x6e\x28\x14\x6c\x41\x39\xc1\x3a\xe1\x9a\xee\x9e\xef\xe4\x13\x5a\xb0\x62\x3b\x16\xe0\x8e\xc5\x99\x46\x51\x9e\x8f\xc0\xd6\xe0\xc9\x48\xe7\x50\x85\x84\x5a\x49\xd5\x38\x4c\x93\x40\x32\xa8\x69\xec\xbf\xa6\xa5\xde\x27\x4f\xa0\x47\xa9\xf7\x5d\x09\x60\xb5\x11\x38\xf6\x88\xcb\x9e\x2d\xbd\xbe\xd2\xe1\x32\xa6\xfd\x59\x83\xdc\x81\x69\x94\x62\x8c\x6d\xfd\x95\xf1\x51\x66\xc8\xbf\x61\x38\xf7\xa8\x84\x78\x1d\xfc\xb9\x36\x14\xef\x15\x7c\xa0\xca\xfe\x67\x70\x9e\x3f\x4b\xbd\xef\x5d\x3f\x5f\xc7\x5f\xa4\xd0\x99\xda\xd0\x3f\x63\x51\x13\xa6\x63\xa8\x73\x44\x63\xa8\x9c\x78\xbc\xe1\xd9\xa7\x1d\x03\xa6\x12\x0c\xee\x95\xe3\x2b\x95\x0e\xa9\x41\xab\x0e\xd5\x93\x85\x9b\x9a\x6a\xe9\xa9\xa0\x77\x83\xee\x90\x40\xa3\x3b\x51\xba\x14\x98\x1f\xad\xd0\xc3\xdd\xae\xb0\x5d\x6d\x1b\xe7\x27\x08\xda\x15\x04\xdb\xe9\xb4\xf8\x5f\x04\xbb\xa4\xed\xbb\x9e\x14\x17\x2f\x38\x21\x72\x07\xd4\x07\x66\x50\xe2\x11\x4b\x72\x2b\x5a\xe3\x91\x10\x1c\xd1\x6c\xb5\x95\xee\xec\x43\x68\xc2\x69\x55\x96\xa8\xdc\x08\xf0\x5b\x86\xb5\x63\xf8\xb3\x13\x4e\x94\x80\xc6\x68\x43\x90\xeb\x8d\x47\x4a\xc2\x6a\x9f\x57\xba\x2b\xfc\x12\x1a\x32\x77\x32\x84\xb7\xec\x43\x3f\x70\x44\x72\xf1\xa2\x3e\x14\xb7\xcd\xbe\xe7\x74\x54\x0b\xb7\x25\x56\x44\xf3\x3d\xf0\x94\xc5\x19\xac\x08\x43\x7a\xc6\x30\xa1\x7f\xe1\x35\x8b\x44\x6c\x65\x08\x06\x6b\xf4\x3f\x15\x88\xbe\x95\x02\xcc\x9c\xff\xc5\xcb\x74\xc2\x80\xf3\xaf\x06\x15\xe5\x87\xce\xfd\x42\x34\x31\x2a\x0c\x0f\xb9\x1f\x71\xb8\xd7\xe6\xdc\xde\x18\x6a\x1f\x3d\xc1\x49\x4b\xbd\xa7\x0c\xe6\x6f\x98\x93\xff\x0d\x00\x00\xff\xff\x98\xcc\x07\xa4\x7d\x25\x00\x00") func templateServerConfTmplBytes() ([]byte, error) { return bindataRead( @@ -167,7 +167,7 @@ func templateServerConfTmpl() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "template/server.conf.tmpl", size: 9595, mode: os.FileMode(420), modTime: time.Unix(1504004418, 0)} + info := bindataFileInfo{name: "template/server.conf.tmpl", size: 9597, mode: os.FileMode(420), modTime: time.Unix(1504030791, 0)} a := &asset{bytes: bytes, info: info} return a, nil } diff --git a/cmd/ovpm/net.go b/cmd/ovpm/net.go index 1723496..30d329f 100644 --- a/cmd/ovpm/net.go +++ b/cmd/ovpm/net.go @@ -49,14 +49,13 @@ var netDefineCommand = cli.Command{ switch ovpm.NetworkTypeFromString(typ) { case ovpm.ROUTE: - if via != "" && !govalidator.IsCIDR(via) { - fmt.Printf("validation error: `%s` must be a network in the CIDR form", via) + if via != "" && !govalidator.IsIPv4(via) { + fmt.Printf("validation error: `%s` must be a network in the IPv4 form", via) fmt.Println() fmt.Println(cli.ShowSubcommandHelp(c)) os.Exit(1) - } else { - via = "" } + case ovpm.SERVERNET: if via != "" { fmt.Println("--via flag can only be used with --type ROUTE") diff --git a/cmd/ovpm/user.go b/cmd/ovpm/user.go index 1ec0fb7..22d8241 100644 --- a/cmd/ovpm/user.go +++ b/cmd/ovpm/user.go @@ -7,6 +7,7 @@ import ( "os" "github.com/Sirupsen/logrus" + "github.com/asaskevich/govalidator" "github.com/cad/ovpm" "github.com/cad/ovpm/pb" "github.com/olekukonko/tablewriter" @@ -87,12 +88,17 @@ var userCreateCommand = cli.Command{ fmt.Println(cli.ShowSubcommandHelp(c)) os.Exit(1) } - + if static != "" && !govalidator.IsIPv4(static) { + fmt.Println("--static flag takes a valid ipv4 address") + fmt.Println() + fmt.Println(cli.ShowSubcommandHelp(c)) + os.Exit(1) + } var hostid uint32 if static != "" { h := ovpm.IP2HostID(net.ParseIP(static).To4()) if h == 0 { - fmt.Println("--static flag takes a valid ipv4 address") + fmt.Printf("can not parse %s as IPv4", static) fmt.Println() fmt.Println(cli.ShowSubcommandHelp(c)) os.Exit(1) @@ -142,6 +148,10 @@ var userUpdateCommand = cli.Command{ Name: "static", Usage: "ip address for the vpn user", }, + cli.BoolFlag{ + Name: "no-static", + Usage: "do not set static ip address for the vpn user", + }, }, Action: func(c *cli.Context) error { action = "user:update" @@ -150,32 +160,64 @@ var userUpdateCommand = cli.Command{ nogw := c.Bool("no-gw") gw := c.Bool("gw") static := c.String("static") + noStatic := c.Bool("no-static") if username == "" { fmt.Println(cli.ShowSubcommandHelp(c)) os.Exit(1) } - if !(password != "" || gw || nogw) { + // Check wether if all flags are are empty. + if !(password != "" || gw || nogw || static != "" || noStatic) { fmt.Println("nothing is updated!") fmt.Println() fmt.Println(cli.ShowSubcommandHelp(c)) os.Exit(1) } + // Given that static is set, check wether it's IPv4. + if static != "" && !govalidator.IsIPv4(static) { + fmt.Println("--static flag takes a valid ipv4 address") + fmt.Println() + fmt.Println(cli.ShowSubcommandHelp(c)) + os.Exit(1) + } + var staticPref pb.UserUpdateRequest_StaticPref + staticPref = pb.UserUpdateRequest_NOPREFSTATIC var hostid uint32 - if static != "" { - h := ovpm.IP2HostID(net.ParseIP(static).To4()) - if h == 0 { - fmt.Println("--static flag takes a valid ipv4 address") - fmt.Println() - fmt.Println(cli.ShowSubcommandHelp(c)) - os.Exit(1) - } - hostid = h + switch { + case static != "" && !noStatic: + // means static is set. + if static != "" { + h := ovpm.IP2HostID(net.ParseIP(static).To4()) + if h == 0 { + fmt.Printf("can't parse %s as IPv4", static) + fmt.Println() + fmt.Println(cli.ShowSubcommandHelp(c)) + os.Exit(1) + } + + hostid = h + } + staticPref = pb.UserUpdateRequest_STATIC + + case static == "" && noStatic: + // means no-static + hostid = 0 + staticPref = pb.UserUpdateRequest_NOSTATIC + case static != "" && noStatic: + // means invalid + fmt.Println("--static flag and --no-static flag cannot be used together") + fmt.Println() + fmt.Println(cli.ShowSubcommandHelp(c)) + os.Exit(1) + case static == "" && !noStatic: + default: + // means no pref + staticPref = pb.UserUpdateRequest_NOPREFSTATIC + hostid = 0 } - var gwPref pb.UserUpdateRequest_GWPref switch { @@ -200,10 +242,11 @@ var userUpdateCommand = cli.Command{ userSvc := pb.NewUserServiceClient(conn) response, err := userSvc.Update(context.Background(), &pb.UserUpdateRequest{ - Username: username, - Password: password, - Gwpref: gwPref, - HostID: hostid, + Username: username, + Password: password, + Gwpref: gwPref, + HostID: hostid, + Staticpref: staticPref, }) if err != nil { diff --git a/cmd/ovpm/vpn.go b/cmd/ovpm/vpn.go index 999fb79..ca131a0 100644 --- a/cmd/ovpm/vpn.go +++ b/cmd/ovpm/vpn.go @@ -6,6 +6,7 @@ import ( "os" "github.com/Sirupsen/logrus" + "github.com/asaskevich/govalidator" "github.com/cad/ovpm" "github.com/cad/ovpm/pb" "github.com/olekukonko/tablewriter" @@ -60,12 +61,16 @@ var vpnInitCommand = cli.Command{ Name: "tcp, t", Usage: "use TCP for vpn protocol, instead of UDP", }, + cli.StringFlag{ + Name: "net, n", + Usage: fmt.Sprintf("VPN network to give clients IP addresses from, in the CIDR form (default: %s)", ovpm.DefaultVPNNetwork), + }, }, Action: func(c *cli.Context) error { action = "vpn:init" hostname := c.String("hostname") if hostname == "" { - logrus.Errorf("'hostname' is needed") + logrus.Errorf("'hostname' is required") fmt.Println(cli.ShowSubcommandHelp(c)) os.Exit(1) @@ -78,13 +83,17 @@ var vpnInitCommand = cli.Command{ tcp := c.Bool("tcp") - var proto pb.VPNProto - - switch tcp { - case true: + proto := pb.VPNProto_UDP + if tcp { proto = pb.VPNProto_TCP - default: - proto = pb.VPNProto_UDP + } + + ipblock := c.String("net") + if ipblock != "" && !govalidator.IsCIDR(ipblock) { + fmt.Println("--net takes an ip network in the CIDR form. e.g. 10.9.0.0/24") + fmt.Println() + fmt.Println(cli.ShowSubcommandHelp(c)) + os.Exit(1) } conn := getConn(c.GlobalString("daemon-port")) @@ -106,7 +115,7 @@ var vpnInitCommand = cli.Command{ okayResponses := []string{"y", "Y", "yes", "Yes", "YES"} nokayResponses := []string{"n", "N", "no", "No", "NO"} if stringInSlice(response, okayResponses) { - if _, err := vpnSvc.Init(context.Background(), &pb.VPNInitRequest{Hostname: hostname, Port: port, Protopref: proto}); err != nil { + if _, err := vpnSvc.Init(context.Background(), &pb.VPNInitRequest{Hostname: hostname, Port: port, Protopref: proto, IPBlock: ipblock}); err != nil { logrus.Errorf("server can not be initialized: %v", err) os.Exit(1) return err diff --git a/const.go b/const.go index 9894140..2a65ce4 100644 --- a/const.go +++ b/const.go @@ -2,11 +2,17 @@ package ovpm const ( // Version defines the version of ovpm. - Version = "0.1.10" + Version = "0.1.11" // DefaultVPNPort is the default OpenVPN port to listen. DefaultVPNPort = "1197" + // DefaultVPNProto is the default OpenVPN protocol to use. + DefaultVPNProto = UDPProto + + // DefaultVPNNetwork is the default OpenVPN network to use. + DefaultVPNNetwork = "10.9.0.0/24" + etcBasePath = "/etc/ovpm/" varBasePath = "/var/db/ovpm/" @@ -20,9 +26,6 @@ const ( _DefaultCAKeyPath = varBasePath + "ca.key" _DefaultDHParamsPath = varBasePath + "dh4096.pem" _DefaultCRLPath = varBasePath + "crl.pem" - - _DefaultServerNetwork = "10.9.0.0" - _DefaultServerNetMask = "255.255.255.0" ) // Testing is used to determine wether we are testing or running normally. diff --git a/net.go b/net.go index 525d22f..0c3f40c 100644 --- a/net.go +++ b/net.go @@ -133,8 +133,8 @@ func CreateNewNetwork(name, cidr string, nettype NetworkType, via string) (*DBNe return nil, fmt.Errorf("validation error: `%s` must be a network in the CIDR form", cidr) } - if !govalidator.IsCIDR(via) && via != "" { - return nil, fmt.Errorf("validation error: `%s` must be a network in the CIDR form", via) + if via != "" && !govalidator.IsIPv4(via) { + return nil, fmt.Errorf("validation error: `%s` must be a network in the IPv4 form", via) } if nettype == UNDEFINEDNET { @@ -146,13 +146,13 @@ func CreateNewNetwork(name, cidr string, nettype NetworkType, via string) (*DBNe return nil, fmt.Errorf("can not parse CIDR %s: %v", cidr, err) } - // Overwrite via with the parsed CIDR string. + // Overwrite via with the parsed IPv4 string. if nettype == ROUTE && via != "" { - _, viaNet, err := net.ParseCIDR(via) + viaIP := net.ParseIP(via).To4() if err != nil { - return nil, fmt.Errorf("can not parse CIDR %s: %v", via, err) + return nil, fmt.Errorf("can not parse IPv4 %s: %v", via, err) } - via = viaNet.String() + via = viaIP.String() } else { via = "" @@ -507,7 +507,7 @@ func HostID2IP(hostid uint32) net.IP { return net.IP(ip) } -//IP2HostID converts an IP address to a host id (32-bit unsigned integer). +// IP2HostID converts an IP address to a host id (32-bit unsigned integer). func IP2HostID(ip net.IP) uint32 { hostid := binary.BigEndian.Uint32(ip) return hostid @@ -515,6 +515,13 @@ func IP2HostID(ip net.IP) uint32 { // IncrementIP will return next ip address within the network. func IncrementIP(ip, mask string) (string, error) { + if !govalidator.IsIPv4(ip) { + return "", fmt.Errorf("'ip' is expected to be a valid IPv4 %s", ip) + } + if !govalidator.IsIPv4(ip) { + return "", fmt.Errorf("'mask' is expected to be a valid IPv4 %s", mask) + } + ipAddr := net.ParseIP(ip).To4() netMask := net.IPMask(net.ParseIP(mask).To4()) ipNet := net.IPNet{IP: ipAddr, Mask: netMask} diff --git a/net_test.go b/net_test.go index 2afaafc..123cbda 100644 --- a/net_test.go +++ b/net_test.go @@ -9,7 +9,7 @@ func TestVPNCreateNewNetwork(t *testing.T) { setupTestCase() SetupDB("sqlite3", ":memory:") defer CeaseDB() - Init("localhost", "", UDPProto) + Init("localhost", "", UDPProto, "") // Prepare: // Test: @@ -56,7 +56,7 @@ func TestVPNDeleteNetwork(t *testing.T) { setupTestCase() SetupDB("sqlite3", ":memory:") defer CeaseDB() - Init("localhost", "", UDPProto) + Init("localhost", "", UDPProto, "") // Prepare: // Test: @@ -94,7 +94,7 @@ func TestVPNGetNetwork(t *testing.T) { setupTestCase() SetupDB("sqlite3", ":memory:") defer CeaseDB() - Init("localhost", "", UDPProto) + Init("localhost", "", UDPProto, "") // Prepare: // Test: @@ -129,7 +129,7 @@ func TestVPNGetAllNetworks(t *testing.T) { setupTestCase() SetupDB("sqlite3", ":memory:") defer CeaseDB() - Init("localhost", "", UDPProto) + Init("localhost", "", UDPProto, "") // Prepare: // Test: @@ -175,7 +175,7 @@ func TestNetAssociate(t *testing.T) { setupTestCase() SetupDB("sqlite3", ":memory:") defer CeaseDB() - Init("localhost", "", UDPProto) + Init("localhost", "", UDPProto, "") // Prepare: // Test: @@ -213,7 +213,7 @@ func TestNetDissociate(t *testing.T) { setupTestCase() SetupDB("sqlite3", ":memory:") defer CeaseDB() - err := Init("localhost", "", UDPProto) + err := Init("localhost", "", UDPProto, "") if err != nil { t.Fatal(err) } @@ -266,7 +266,7 @@ func TestNetGetAssociatedUsers(t *testing.T) { setupTestCase() SetupDB("sqlite3", ":memory:") defer CeaseDB() - Init("localhost", "", UDPProto) + Init("localhost", "", UDPProto, "") // Prepare: // Test: diff --git a/pb/user.pb.go b/pb/user.pb.go index d96f0c7..9a45004 100644 --- a/pb/user.pb.go +++ b/pb/user.pb.go @@ -86,6 +86,32 @@ func (x UserUpdateRequest_GWPref) String() string { } func (UserUpdateRequest_GWPref) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{2, 0} } +type UserUpdateRequest_StaticPref int32 + +const ( + UserUpdateRequest_NOPREFSTATIC UserUpdateRequest_StaticPref = 0 + UserUpdateRequest_NOSTATIC UserUpdateRequest_StaticPref = 1 + UserUpdateRequest_STATIC UserUpdateRequest_StaticPref = 2 +) + +var UserUpdateRequest_StaticPref_name = map[int32]string{ + 0: "NOPREFSTATIC", + 1: "NOSTATIC", + 2: "STATIC", +} +var UserUpdateRequest_StaticPref_value = map[string]int32{ + "NOPREFSTATIC": 0, + "NOSTATIC": 1, + "STATIC": 2, +} + +func (x UserUpdateRequest_StaticPref) String() string { + return proto.EnumName(UserUpdateRequest_StaticPref_name, int32(x)) +} +func (UserUpdateRequest_StaticPref) EnumDescriptor() ([]byte, []int) { + return fileDescriptor0, []int{2, 1} +} + type UserListRequest struct { } @@ -135,10 +161,11 @@ func (m *UserCreateRequest) GetHostID() uint32 { } type UserUpdateRequest struct { - Username string `protobuf:"bytes,1,opt,name=Username" json:"Username,omitempty"` - Password string `protobuf:"bytes,2,opt,name=Password" json:"Password,omitempty"` - Gwpref UserUpdateRequest_GWPref `protobuf:"varint,3,opt,name=gwpref,enum=pb.UserUpdateRequest_GWPref" json:"gwpref,omitempty"` - HostID uint32 `protobuf:"varint,4,opt,name=HostID" json:"HostID,omitempty"` + Username string `protobuf:"bytes,1,opt,name=Username" json:"Username,omitempty"` + Password string `protobuf:"bytes,2,opt,name=Password" json:"Password,omitempty"` + Gwpref UserUpdateRequest_GWPref `protobuf:"varint,3,opt,name=gwpref,enum=pb.UserUpdateRequest_GWPref" json:"gwpref,omitempty"` + HostID uint32 `protobuf:"varint,4,opt,name=HostID" json:"HostID,omitempty"` + Staticpref UserUpdateRequest_StaticPref `protobuf:"varint,5,opt,name=staticpref,enum=pb.UserUpdateRequest_StaticPref" json:"staticpref,omitempty"` } func (m *UserUpdateRequest) Reset() { *m = UserUpdateRequest{} } @@ -174,6 +201,13 @@ func (m *UserUpdateRequest) GetHostID() uint32 { return 0 } +func (m *UserUpdateRequest) GetStaticpref() UserUpdateRequest_StaticPref { + if m != nil { + return m.Staticpref + } + return UserUpdateRequest_NOPREFSTATIC +} + type UserDeleteRequest struct { Username string `protobuf:"bytes,1,opt,name=Username" json:"Username,omitempty"` } @@ -329,6 +363,7 @@ func init() { proto.RegisterType((*UserResponse_User)(nil), "pb.UserResponse.User") proto.RegisterType((*UserGenConfigResponse)(nil), "pb.UserGenConfigResponse") proto.RegisterEnum("pb.UserUpdateRequest_GWPref", UserUpdateRequest_GWPref_name, UserUpdateRequest_GWPref_value) + proto.RegisterEnum("pb.UserUpdateRequest_StaticPref", UserUpdateRequest_StaticPref_name, UserUpdateRequest_StaticPref_value) } // Reference imports to suppress errors if they are not otherwise used. @@ -571,41 +606,45 @@ var _UserService_serviceDesc = grpc.ServiceDesc{ func init() { proto.RegisterFile("user.proto", fileDescriptor0) } var fileDescriptor0 = []byte{ - // 575 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x94, 0x4d, 0x6e, 0xd3, 0x40, - 0x14, 0xc7, 0xb1, 0x9b, 0x98, 0xe4, 0xf5, 0x2b, 0x9d, 0xa6, 0xe0, 0x5a, 0x41, 0x8a, 0x66, 0x81, - 0xa2, 0x22, 0xd9, 0x22, 0xb0, 0x2a, 0x2b, 0x94, 0x82, 0x29, 0x82, 0x34, 0x72, 0x55, 0x65, 0x89, - 0x9c, 0xe4, 0x25, 0xb2, 0x94, 0x7a, 0xcc, 0xcc, 0xa4, 0xd9, 0x23, 0x6e, 0xc0, 0x89, 0xd8, 0x70, - 0x01, 0xae, 0xc0, 0x01, 0x38, 0x02, 0x9a, 0x19, 0xc7, 0x21, 0x21, 0xa0, 0x2c, 0xd8, 0xcd, 0xfb, - 0xfa, 0x8d, 0xdf, 0x7b, 0xff, 0x31, 0xc0, 0x4c, 0x20, 0xf7, 0x33, 0xce, 0x24, 0x23, 0x76, 0x36, - 0xf0, 0x1a, 0x13, 0xc6, 0x26, 0x53, 0x0c, 0xe2, 0x2c, 0x09, 0xe2, 0x34, 0x65, 0x32, 0x96, 0x09, - 0x4b, 0x85, 0xc9, 0xa0, 0x47, 0x70, 0x78, 0x23, 0x90, 0xbf, 0x4b, 0x84, 0x8c, 0xf0, 0xe3, 0x0c, - 0x85, 0xa4, 0x73, 0x38, 0x52, 0xae, 0x0e, 0xc7, 0x58, 0x62, 0xee, 0x24, 0x1e, 0x54, 0x94, 0x33, - 0x8d, 0x6f, 0xd1, 0xb5, 0x9a, 0x56, 0xab, 0x1a, 0x15, 0xb6, 0x8a, 0xf5, 0x62, 0x21, 0xe6, 0x8c, - 0x8f, 0x5c, 0xdb, 0xc4, 0x16, 0x36, 0x21, 0x50, 0xea, 0xb2, 0xb0, 0xef, 0xee, 0x34, 0xad, 0x56, - 0x25, 0xd2, 0x67, 0xf2, 0x00, 0x9c, 0x37, 0x4c, 0xc8, 0xcb, 0x0b, 0xb7, 0xd4, 0xb4, 0x5a, 0xfb, - 0x51, 0x6e, 0xd1, 0xaf, 0x96, 0xb9, 0xf9, 0x26, 0x1b, 0xfd, 0x87, 0x9b, 0x9f, 0x83, 0x33, 0x99, - 0x67, 0x1c, 0xc7, 0xfa, 0xee, 0x83, 0x76, 0xc3, 0xcf, 0x06, 0xfe, 0x1f, 0x78, 0x3f, 0xec, 0xf7, - 0x38, 0x8e, 0xa3, 0x3c, 0xf7, 0xaf, 0xdf, 0xf6, 0x18, 0x1c, 0x93, 0x49, 0x00, 0x9c, 0xee, 0x55, - 0x2f, 0x7a, 0xf5, 0xba, 0x76, 0x8f, 0x54, 0xa0, 0xd4, 0xbd, 0x0a, 0xfb, 0x35, 0x8b, 0x38, 0x60, - 0x87, 0xfd, 0x9a, 0x4d, 0x03, 0xd3, 0xc2, 0x05, 0x4e, 0x71, 0xab, 0x16, 0xa8, 0x0f, 0x35, 0x75, - 0x8e, 0x30, 0xc5, 0xf9, 0x36, 0xf9, 0x6d, 0xa8, 0xab, 0x73, 0x88, 0x69, 0x87, 0xa5, 0xe3, 0x64, - 0xb2, 0x4d, 0xcd, 0x67, 0x1b, 0xf6, 0xcc, 0x25, 0x22, 0x63, 0xa9, 0x40, 0xf2, 0x04, 0xca, 0x4a, - 0x25, 0xc2, 0xb5, 0x9a, 0x3b, 0xad, 0xdd, 0xf6, 0xc9, 0x62, 0x34, 0x8b, 0x04, 0x63, 0x98, 0x1c, - 0xef, 0x9b, 0x05, 0x25, 0x65, 0xff, 0x73, 0x13, 0x3e, 0x90, 0x6b, 0xe4, 0x77, 0xc8, 0xaf, 0x91, - 0x27, 0xf1, 0xb4, 0x3b, 0xbb, 0x1d, 0x20, 0xcf, 0x77, 0xb2, 0x21, 0xa2, 0x74, 0xd1, 0x41, 0x2e, - 0xf5, 0x6e, 0xaa, 0x91, 0x3e, 0x93, 0x06, 0x54, 0x8d, 0xe8, 0x46, 0x2f, 0xa5, 0x1e, 0x7f, 0x35, - 0x5a, 0x3a, 0x48, 0x1d, 0xca, 0x97, 0xbd, 0x2e, 0x4a, 0xb7, 0xac, 0x23, 0xc6, 0x28, 0xf4, 0xe5, - 0x6c, 0xd4, 0xd7, 0xfd, 0x95, 0x1d, 0xbe, 0x80, 0x93, 0xb5, 0xd1, 0xe5, 0xe3, 0xa0, 0xb0, 0xd7, - 0x99, 0x26, 0x98, 0x4a, 0xe3, 0xcf, 0x9b, 0x5b, 0xf1, 0xb5, 0x7f, 0xee, 0xc0, 0xae, 0xaa, 0x56, - 0xbd, 0x24, 0x43, 0x24, 0x21, 0x94, 0xd4, 0xa3, 0x21, 0xc7, 0x8b, 0xd9, 0xfd, 0xf6, 0x84, 0xbc, - 0xda, 0xfa, 0x40, 0xa9, 0xfb, 0xe9, 0xfb, 0x8f, 0x2f, 0x36, 0xa1, 0xfb, 0xc1, 0xdd, 0xd3, 0x40, - 0xcd, 0x35, 0x98, 0x26, 0x42, 0x9e, 0x5b, 0x67, 0xe4, 0x3d, 0x38, 0xa6, 0x49, 0x52, 0xac, 0x61, - 0xe5, 0xe9, 0x6d, 0x80, 0x79, 0x1a, 0x56, 0xa7, 0x87, 0x05, 0x6c, 0xa8, 0x2b, 0x72, 0x9c, 0x11, - 0xf8, 0x12, 0xb7, 0x22, 0xf8, 0xad, 0x70, 0x33, 0x5d, 0x91, 0xe3, 0x8c, 0x96, 0x97, 0xb8, 0x15, - 0x6d, 0x6f, 0x85, 0x1b, 0xe9, 0x0a, 0x85, 0x7b, 0x0b, 0x65, 0xad, 0x74, 0x52, 0x5f, 0x96, 0x2d, - 0x85, 0xbf, 0x01, 0x76, 0xaa, 0x61, 0xc7, 0xf4, 0xa0, 0x80, 0x71, 0x55, 0xa0, 0x58, 0x1f, 0xa0, - 0x5a, 0xac, 0x92, 0xb8, 0x8b, 0xca, 0xf5, 0x87, 0xe1, 0x9d, 0x6e, 0x88, 0xe4, 0xf0, 0x47, 0x1a, - 0xfe, 0x90, 0x92, 0x02, 0x3e, 0xc1, 0x74, 0xa8, 0x73, 0xce, 0xad, 0xb3, 0x81, 0xa3, 0x7f, 0x91, - 0xcf, 0x7e, 0x05, 0x00, 0x00, 0xff, 0xff, 0xc8, 0x3d, 0xc7, 0xac, 0x52, 0x05, 0x00, 0x00, + // 628 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x94, 0xc1, 0x6e, 0xd3, 0x4c, + 0x10, 0xc7, 0x6b, 0x37, 0xf1, 0x97, 0x4c, 0xd3, 0xd6, 0xdd, 0xa6, 0x1f, 0x6e, 0x54, 0xa4, 0x68, + 0x0f, 0x28, 0x2a, 0x52, 0x22, 0x02, 0x07, 0x54, 0x2e, 0x54, 0x29, 0x98, 0x22, 0x70, 0x23, 0xa7, + 0x55, 0x8e, 0xc8, 0x49, 0xa6, 0x91, 0xa5, 0xd4, 0x36, 0xbb, 0x9b, 0xe6, 0x8e, 0x78, 0x03, 0x9e, + 0x87, 0x2b, 0x2f, 0xc0, 0x2b, 0xf0, 0x00, 0x3c, 0x02, 0xda, 0x5d, 0xc7, 0x6e, 0x8a, 0x41, 0x39, + 0x70, 0x9b, 0x99, 0x9d, 0xf9, 0x8d, 0x77, 0xf6, 0x3f, 0x06, 0x98, 0x73, 0x64, 0xed, 0x84, 0xc5, + 0x22, 0x26, 0x66, 0x32, 0x6a, 0x1c, 0x4d, 0xe3, 0x78, 0x3a, 0xc3, 0x4e, 0x90, 0x84, 0x9d, 0x20, + 0x8a, 0x62, 0x11, 0x88, 0x30, 0x8e, 0xb8, 0xce, 0xa0, 0x7b, 0xb0, 0x7b, 0xc5, 0x91, 0xbd, 0x0b, + 0xb9, 0xf0, 0xf1, 0xe3, 0x1c, 0xb9, 0xa0, 0x0b, 0xd8, 0x93, 0xa1, 0x1e, 0xc3, 0x40, 0x60, 0x1a, + 0x24, 0x0d, 0xa8, 0xc8, 0x60, 0x14, 0xdc, 0xa0, 0x63, 0x34, 0x8d, 0x56, 0xd5, 0xcf, 0x7c, 0x79, + 0xd6, 0x0f, 0x38, 0x5f, 0xc4, 0x6c, 0xe2, 0x98, 0xfa, 0x6c, 0xe9, 0x13, 0x02, 0x25, 0x2f, 0x76, + 0x87, 0xce, 0x66, 0xd3, 0x68, 0x55, 0x7c, 0x65, 0x93, 0xff, 0xc1, 0x7a, 0x13, 0x73, 0x71, 0x7e, + 0xe6, 0x94, 0x9a, 0x46, 0x6b, 0xdb, 0x4f, 0x3d, 0xfa, 0xd5, 0xd4, 0x9d, 0xaf, 0x92, 0xc9, 0x3f, + 0xe8, 0xfc, 0x0c, 0xac, 0xe9, 0x22, 0x61, 0x78, 0xad, 0x7a, 0xef, 0x74, 0x8f, 0xda, 0xc9, 0xa8, + 0xfd, 0x1b, 0xbe, 0xed, 0x0e, 0xfb, 0x0c, 0xaf, 0xfd, 0x34, 0xf7, 0x4f, 0xdf, 0x46, 0x5e, 0x02, + 0x70, 0x39, 0xb9, 0xb1, 0x22, 0x96, 0x15, 0xb1, 0x59, 0x4c, 0x1c, 0xa8, 0x3c, 0x45, 0xbd, 0x53, + 0x43, 0x1f, 0x81, 0xa5, 0x7b, 0x11, 0x00, 0xcb, 0xbb, 0xe8, 0xfb, 0xaf, 0x5e, 0xdb, 0x1b, 0xa4, + 0x02, 0x25, 0xef, 0xc2, 0x1d, 0xda, 0x06, 0xb1, 0xc0, 0x74, 0x87, 0xb6, 0x49, 0x9f, 0x03, 0xe4, + 0x04, 0x62, 0x43, 0x4d, 0xe7, 0x0e, 0x2e, 0x4f, 0x2f, 0xcf, 0x7b, 0xf6, 0x06, 0xa9, 0x41, 0xc5, + 0xbb, 0x48, 0x3d, 0x43, 0xb2, 0x52, 0xdb, 0xa4, 0x1d, 0x3d, 0xbe, 0x33, 0x9c, 0xe1, 0x5a, 0xe3, + 0xa3, 0x6d, 0xb0, 0xa5, 0xed, 0x63, 0x84, 0x8b, 0x75, 0xf2, 0xbb, 0x50, 0x97, 0xb6, 0x8b, 0x51, + 0x2f, 0x8e, 0xae, 0xc3, 0xe9, 0x3a, 0x35, 0x9f, 0x4d, 0xa8, 0xe9, 0x26, 0x3c, 0x89, 0x23, 0x8e, + 0xe4, 0x31, 0x94, 0xa5, 0x42, 0xb9, 0x63, 0x34, 0x37, 0x5b, 0x5b, 0xdd, 0x83, 0xe5, 0x10, 0x97, + 0x09, 0xda, 0xd1, 0x39, 0x8d, 0x6f, 0x06, 0x94, 0xa4, 0xff, 0x57, 0x15, 0xb4, 0x81, 0x0c, 0x90, + 0xdd, 0x22, 0x1b, 0x20, 0x0b, 0x83, 0x99, 0x37, 0xbf, 0x19, 0x21, 0x4b, 0xf5, 0x50, 0x70, 0x22, + 0x35, 0xd9, 0x43, 0x26, 0x94, 0x2e, 0xaa, 0xbe, 0xb2, 0xc9, 0x11, 0x54, 0xb5, 0xe0, 0x27, 0xa7, + 0x42, 0x3d, 0x7d, 0xd5, 0xcf, 0x03, 0xa4, 0x0e, 0xe5, 0xf3, 0xbe, 0x87, 0x42, 0x3d, 0x7c, 0xd5, + 0xd7, 0x4e, 0xa6, 0x6d, 0xab, 0x50, 0xdb, 0xff, 0xad, 0x68, 0xfb, 0x05, 0x1c, 0xdc, 0x1b, 0x5d, + 0x3a, 0x0e, 0x0a, 0xb5, 0xde, 0x2c, 0xc4, 0x48, 0xe8, 0x78, 0x7a, 0xb9, 0x95, 0x58, 0xf7, 0xe7, + 0x26, 0x6c, 0xc9, 0x6a, 0x79, 0x97, 0x70, 0x8c, 0xc4, 0x85, 0x92, 0x5c, 0x58, 0xb2, 0xbf, 0x9c, + 0xdd, 0x9d, 0xf5, 0x6d, 0xd8, 0xf7, 0x07, 0x4a, 0x9d, 0x4f, 0xdf, 0x7f, 0x7c, 0x31, 0x09, 0xdd, + 0xee, 0xdc, 0x3e, 0xe9, 0xc8, 0xb9, 0x76, 0x66, 0x21, 0x17, 0x27, 0xc6, 0x31, 0x79, 0x0f, 0x96, + 0xbe, 0x24, 0xc9, 0x9e, 0x61, 0x65, 0xed, 0x0b, 0x60, 0x0d, 0x05, 0xab, 0xd3, 0xdd, 0x0c, 0x36, + 0x56, 0x15, 0x29, 0x4e, 0xaf, 0x42, 0x8e, 0x5b, 0x59, 0x8d, 0xb5, 0x70, 0x73, 0x55, 0x91, 0xe2, + 0xb4, 0x96, 0x73, 0xdc, 0x8a, 0xb6, 0xd7, 0xc2, 0x4d, 0x54, 0x85, 0xc4, 0xbd, 0x85, 0xb2, 0x52, + 0x3a, 0xa9, 0xe7, 0x65, 0xb9, 0xf0, 0x0b, 0x60, 0x87, 0x0a, 0xb6, 0x4f, 0x77, 0x32, 0x18, 0x93, + 0x05, 0x92, 0xf5, 0x01, 0xaa, 0xd9, 0x53, 0x12, 0x67, 0x59, 0x79, 0x7f, 0x31, 0x1a, 0x87, 0x05, + 0x27, 0x29, 0xfc, 0xa1, 0x82, 0x3f, 0xa0, 0x24, 0x83, 0x4f, 0x31, 0x1a, 0xab, 0x9c, 0x13, 0xe3, + 0x78, 0x64, 0xa9, 0xdf, 0xf3, 0xd3, 0x5f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x92, 0x5d, 0x0b, 0xf4, + 0xce, 0x05, 0x00, 0x00, } diff --git a/pb/user.proto b/pb/user.proto index 47badfa..8114a2a 100644 --- a/pb/user.proto +++ b/pb/user.proto @@ -25,6 +25,12 @@ message UserUpdateRequest { } GWPref gwpref = 3; uint32 HostID = 4; + enum StaticPref { + NOPREFSTATIC = 0; + NOSTATIC = 1; + STATIC = 2; + } + StaticPref staticpref = 5; } diff --git a/pb/user.swagger.json b/pb/user.swagger.json index 0e3f46b..3dc2a3d 100644 --- a/pb/user.swagger.json +++ b/pb/user.swagger.json @@ -210,6 +210,15 @@ ], "default": "NOPREF" }, + "UserUpdateRequestStaticPref": { + "type": "string", + "enum": [ + "NOPREFSTATIC", + "NOSTATIC", + "STATIC" + ], + "default": "NOPREFSTATIC" + }, "pbUserCreateRequest": { "type": "object", "properties": { @@ -290,6 +299,9 @@ "HostID": { "type": "integer", "format": "int64" + }, + "staticpref": { + "$ref": "#/definitions/UserUpdateRequestStaticPref" } } } diff --git a/pb/vpn.pb.go b/pb/vpn.pb.go index 27c13dc..0cd2d12 100644 --- a/pb/vpn.pb.go +++ b/pb/vpn.pb.go @@ -54,6 +54,7 @@ type VPNInitRequest struct { Hostname string `protobuf:"bytes,1,opt,name=Hostname" json:"Hostname,omitempty"` Port string `protobuf:"bytes,2,opt,name=Port" json:"Port,omitempty"` Protopref VPNProto `protobuf:"varint,3,opt,name=Protopref,enum=pb.VPNProto" json:"Protopref,omitempty"` + IPBlock string `protobuf:"bytes,4,opt,name=IPBlock" json:"IPBlock,omitempty"` } func (m *VPNInitRequest) Reset() { *m = VPNInitRequest{} } @@ -82,6 +83,13 @@ func (m *VPNInitRequest) GetProtopref() VPNProto { return VPNProto_NOPREF } +func (m *VPNInitRequest) GetIPBlock() string { + if m != nil { + return m.IPBlock + } + return "" +} + type VPNStatusResponse struct { Name string `protobuf:"bytes,1,opt,name=Name" json:"Name,omitempty"` SerialNumber string `protobuf:"bytes,2,opt,name=SerialNumber" json:"SerialNumber,omitempty"` @@ -294,31 +302,32 @@ var _VPNService_serviceDesc = grpc.ServiceDesc{ func init() { proto.RegisterFile("vpn.proto", fileDescriptor1) } var fileDescriptor1 = []byte{ - // 406 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x92, 0xc1, 0x72, 0xd3, 0x30, - 0x10, 0x86, 0xb1, 0x93, 0xba, 0xf1, 0x4e, 0x26, 0x38, 0xdb, 0x02, 0x22, 0xd3, 0x43, 0x47, 0xa7, - 0x4c, 0x0e, 0xf1, 0x50, 0x6e, 0xbd, 0x75, 0x0c, 0x4c, 0x39, 0x60, 0x34, 0x2e, 0xe4, 0x2e, 0x83, - 0xe8, 0x78, 0x48, 0x25, 0x21, 0x29, 0xbe, 0xc3, 0x2b, 0xf0, 0x12, 0xbc, 0x0f, 0xaf, 0xc0, 0x83, - 0x30, 0x92, 0xdd, 0x26, 0x66, 0x86, 0xdb, 0xbf, 0xdf, 0x66, 0x77, 0xff, 0xfc, 0x16, 0xa4, 0xad, - 0x96, 0x6b, 0x6d, 0x94, 0x53, 0x18, 0xeb, 0x7a, 0x71, 0x76, 0xab, 0xd4, 0xed, 0x56, 0xe4, 0x5c, - 0x37, 0x39, 0x97, 0x52, 0x39, 0xee, 0x1a, 0x25, 0x6d, 0xf7, 0x0b, 0x8a, 0x90, 0x6d, 0x58, 0x79, - 0xe3, 0xb8, 0xdb, 0xd9, 0x4a, 0x7c, 0xdb, 0x09, 0xeb, 0xe8, 0x16, 0x66, 0x1b, 0x56, 0xbe, 0x95, - 0x8d, 0xeb, 0x09, 0x2e, 0x60, 0x72, 0xad, 0xac, 0x93, 0xfc, 0x4e, 0x90, 0xe8, 0x3c, 0x5a, 0xa6, - 0xd5, 0x43, 0x8d, 0x08, 0x63, 0xa6, 0x8c, 0x23, 0x71, 0xe0, 0x41, 0xe3, 0x0a, 0x52, 0xe6, 0xd7, - 0x6b, 0x23, 0xbe, 0x90, 0xd1, 0x79, 0xb4, 0x9c, 0x5d, 0x4c, 0xd7, 0xba, 0x5e, 0x6f, 0x58, 0x19, - 0x78, 0xb5, 0x6f, 0xd3, 0xef, 0x31, 0xcc, 0x0f, 0x2c, 0x58, 0xad, 0xa4, 0x0d, 0x5b, 0xcb, 0xfd, - 0xb5, 0xa0, 0x91, 0xc2, 0xf4, 0x46, 0x98, 0x86, 0x6f, 0xcb, 0xdd, 0x5d, 0x2d, 0x4c, 0x7f, 0x71, - 0xc0, 0x06, 0x4e, 0x47, 0xff, 0x71, 0x3a, 0x3e, 0x70, 0x8a, 0x30, 0x2e, 0x84, 0x71, 0xe4, 0xa8, - 0x63, 0x5e, 0xe3, 0x53, 0x48, 0x8a, 0xab, 0x40, 0x93, 0x40, 0xfb, 0x0a, 0x33, 0x18, 0x95, 0xc2, - 0x91, 0xe3, 0x00, 0xbd, 0xf4, 0xd3, 0xef, 0xb8, 0xfd, 0x4a, 0x26, 0xdd, 0xb4, 0xd7, 0x78, 0x06, - 0x69, 0x61, 0x04, 0x77, 0xe2, 0xf3, 0x95, 0x23, 0x69, 0x68, 0xec, 0x01, 0x9e, 0xc2, 0x51, 0xf8, - 0xeb, 0x04, 0x42, 0xa7, 0x2b, 0xe8, 0x1c, 0x1e, 0x3f, 0x24, 0xde, 0x05, 0xb0, 0x5a, 0xc2, 0xe4, - 0x3e, 0x2d, 0x04, 0x48, 0xca, 0xf7, 0xac, 0x7a, 0xfd, 0x26, 0x7b, 0x84, 0xc7, 0x30, 0xfa, 0xf8, - 0x8a, 0x65, 0x91, 0x17, 0x1f, 0x0a, 0x96, 0xc5, 0x17, 0xbf, 0x22, 0x00, 0x1f, 0xa0, 0x30, 0x6d, - 0xf3, 0x49, 0x20, 0x83, 0xa4, 0xcb, 0x12, 0x4f, 0xfb, 0xc8, 0x07, 0x5f, 0x77, 0xf1, 0xe4, 0x1f, - 0xda, 0xdd, 0xa3, 0xcf, 0x7f, 0xfc, 0xfe, 0xf3, 0x33, 0x3e, 0xa1, 0xb3, 0xbc, 0x7d, 0x91, 0xb7, - 0x5a, 0xe6, 0x36, 0xf4, 0x2f, 0xa3, 0x15, 0x5e, 0xc3, 0xd8, 0x5b, 0x43, 0xec, 0x27, 0x0f, 0x5e, - 0xc6, 0xe2, 0x64, 0xc0, 0xfa, 0x5d, 0xcf, 0xc2, 0xae, 0x39, 0x9d, 0xde, 0xef, 0x6a, 0x64, 0xe3, - 0x2e, 0xa3, 0x55, 0x9d, 0x84, 0x47, 0xf7, 0xf2, 0x6f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xfc, 0x94, - 0xe6, 0xba, 0xa3, 0x02, 0x00, 0x00, + // 423 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x92, 0xcf, 0x72, 0xd3, 0x30, + 0x10, 0xc6, 0xb1, 0xe3, 0x3a, 0xf1, 0x4e, 0x26, 0x38, 0xdb, 0x02, 0x22, 0xd3, 0x43, 0x47, 0xa7, + 0x4c, 0x0e, 0xf1, 0x50, 0x6e, 0xbd, 0x95, 0x00, 0xd3, 0x1e, 0x30, 0x9a, 0x14, 0x72, 0x57, 0x8a, + 0xe8, 0x78, 0x9a, 0x4a, 0x42, 0x52, 0x72, 0x87, 0x03, 0x2f, 0xc0, 0x4b, 0xf0, 0x3e, 0xbc, 0x02, + 0x0f, 0xc2, 0x48, 0x76, 0xfe, 0x98, 0x99, 0xde, 0xbe, 0xfd, 0xad, 0x77, 0xbd, 0xfb, 0xad, 0x20, + 0xdb, 0x68, 0x39, 0xd5, 0x46, 0x39, 0x85, 0xb1, 0x5e, 0x8e, 0x4e, 0xef, 0x94, 0xba, 0x5b, 0x89, + 0x82, 0xeb, 0xaa, 0xe0, 0x52, 0x2a, 0xc7, 0x5d, 0xa5, 0xa4, 0xad, 0xbf, 0xa0, 0x08, 0xf9, 0x82, + 0x95, 0x37, 0x8e, 0xbb, 0xb5, 0x9d, 0x8b, 0x6f, 0x6b, 0x61, 0x1d, 0xfd, 0x19, 0xc1, 0x60, 0xc1, + 0xca, 0x6b, 0x59, 0xb9, 0x06, 0xe1, 0x08, 0x7a, 0x57, 0xca, 0x3a, 0xc9, 0x1f, 0x04, 0x89, 0xce, + 0xa2, 0x71, 0x36, 0xdf, 0xc5, 0x88, 0x90, 0x30, 0x65, 0x1c, 0x89, 0x03, 0x0f, 0x1a, 0x27, 0x90, + 0x31, 0xdf, 0x5f, 0x1b, 0xf1, 0x95, 0x74, 0xce, 0xa2, 0xf1, 0xe0, 0xbc, 0x3f, 0xd5, 0xcb, 0xe9, + 0x82, 0x95, 0x81, 0xcf, 0xf7, 0x69, 0x24, 0xd0, 0xbd, 0x66, 0x6f, 0x56, 0xea, 0xf6, 0x9e, 0x24, + 0xa1, 0xc5, 0x36, 0xa4, 0xdf, 0x63, 0x18, 0x1e, 0x4c, 0x67, 0xb5, 0x92, 0x36, 0xfc, 0xaf, 0xdc, + 0xcf, 0x11, 0x34, 0x52, 0xe8, 0xdf, 0x08, 0x53, 0xf1, 0x55, 0xb9, 0x7e, 0x58, 0x0a, 0xd3, 0xcc, + 0xd2, 0x62, 0xad, 0x1d, 0x3a, 0x8f, 0xec, 0x90, 0x1c, 0xec, 0x80, 0x90, 0xcc, 0x84, 0x71, 0xe4, + 0xa8, 0x66, 0x5e, 0xe3, 0x73, 0x48, 0x67, 0x97, 0x81, 0xa6, 0x81, 0x36, 0x11, 0xe6, 0xd0, 0x29, + 0x85, 0x23, 0xdd, 0x00, 0xbd, 0xf4, 0xd5, 0x1f, 0xb8, 0xbd, 0x27, 0xbd, 0xba, 0xda, 0x6b, 0x3c, + 0x85, 0x6c, 0x66, 0x04, 0x77, 0xe2, 0xcb, 0xa5, 0x23, 0x59, 0x48, 0xec, 0x01, 0x9e, 0xc0, 0x51, + 0x30, 0x85, 0x40, 0xc8, 0xd4, 0x01, 0x1d, 0xc2, 0xd3, 0xdd, 0x2d, 0x6a, 0x03, 0x26, 0x63, 0xe8, + 0x6d, 0x7d, 0x44, 0x80, 0xb4, 0xfc, 0xc8, 0xe6, 0xef, 0xde, 0xe7, 0x4f, 0xb0, 0x0b, 0x9d, 0xcf, + 0x6f, 0x59, 0x1e, 0x79, 0xf1, 0x69, 0xc6, 0xf2, 0xf8, 0xfc, 0x77, 0x04, 0xe0, 0x0d, 0x14, 0x66, + 0x53, 0xdd, 0x0a, 0x64, 0x90, 0xd6, 0x5e, 0xe2, 0x49, 0x73, 0x8c, 0xd6, 0xe1, 0x47, 0xcf, 0xfe, + 0xa3, 0xf5, 0xff, 0xe8, 0xcb, 0x1f, 0x7f, 0xfe, 0xfe, 0x8a, 0x8f, 0xe9, 0xa0, 0xd8, 0xbc, 0x2a, + 0x36, 0x5a, 0x16, 0x36, 0xe4, 0x2f, 0xa2, 0x09, 0x5e, 0x41, 0xe2, 0x47, 0x43, 0x6c, 0x2a, 0x0f, + 0xde, 0xcc, 0xe8, 0xb8, 0xc5, 0x9a, 0x5e, 0x2f, 0x42, 0xaf, 0x21, 0xed, 0x6f, 0x7b, 0x55, 0xb2, + 0x72, 0x17, 0xd1, 0x64, 0x99, 0x86, 0xf7, 0xf8, 0xfa, 0x5f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x93, + 0x52, 0x74, 0x1b, 0xbe, 0x02, 0x00, 0x00, } diff --git a/pb/vpn.proto b/pb/vpn.proto index 2b5ea30..a3b7467 100644 --- a/pb/vpn.proto +++ b/pb/vpn.proto @@ -15,6 +15,7 @@ message VPNInitRequest { string Hostname = 1; string Port = 2; VPNProto Protopref = 3; + string IPBlock = 4; } service VPNService { diff --git a/pb/vpn.swagger.json b/pb/vpn.swagger.json index 6bc071d..08344d5 100644 --- a/pb/vpn.swagger.json +++ b/pb/vpn.swagger.json @@ -80,6 +80,9 @@ }, "Protopref": { "$ref": "#/definitions/pbVPNProto" + }, + "IPBlock": { + "type": "string" } } }, diff --git a/template/server.conf.tmpl b/template/server.conf.tmpl index 6179a7f..85d2984 100644 --- a/template/server.conf.tmpl +++ b/template/server.conf.tmpl @@ -248,8 +248,8 @@ comp-lzo # # You can uncomment this out on # non-Windows systems. -user nobody -group nobody +user openvpn +group openvpn # The persist options will try to avoid # accessing certain resources on restart diff --git a/user.go b/user.go index 09a43b5..f94d34d 100644 --- a/user.go +++ b/user.go @@ -170,7 +170,6 @@ func (u *DBUser) Update(password string, nogw bool, hostid uint32) error { u.NoGW = nogw u.HostID = hostid - db.Save(u) if hostid != 0 { server, err := GetServerInstance() @@ -192,6 +191,7 @@ func (u *DBUser) Update(password string, nogw bool, hostid uint32) error { return fmt.Errorf("ip %s is already allocated", ip) } } + db.Save(u) err := Emit() if err != nil { @@ -244,6 +244,8 @@ func (u *DBUser) ResetPassword(password string) error { // // This is often used to sign users when the current CA is changed while there are // still existing users in the database. +// +// Also it can be used when a user cert is expired or user's private key stolen, missing etc. func (u *DBUser) Renew() error { if !IsInitialized() { return fmt.Errorf("you first need to create server") @@ -301,37 +303,47 @@ func (u *DBUser) GetCreatedAt() string { func (u *DBUser) getIP() net.IP { users := getNonStaticHostUsers() staticHostIDs := getStaticHostIDs() - mask := net.IPMask(net.ParseIP(_DefaultServerNetMask).To4()) - network := net.ParseIP(_DefaultServerNetwork).To4().Mask(mask) + server, err := GetServerInstance() + if err != nil { + logrus.Panicf("can not get server instance: %v", err) + } + mask := net.IPMask(net.ParseIP(server.Mask).To4()) + network := net.ParseIP(server.Net).To4().Mask(mask) - // Host is static? + // If the user has static ip address, return it immediately. if u.HostID != 0 { - // Host is really static? - if hostIDsContains(staticHostIDs, u.HostID) { - return HostID2IP(u.HostID) - } - return nil + return HostID2IP(u.HostID) } - // Host is dynamic. - for i, user := range users { - hostID := IP2HostID(network) + uint32(i+2) - if hostIDsContains(staticHostIDs, hostID) { - for hostIDsContains(staticHostIDs, hostID) { - i++ - hostID = IP2HostID(network) + uint32(i+1) - } + // Calculate dynamic ip addresses from a deterministic address pool. + freeHostID := 0 + for _, user := range users { + // Skip, if user is supposed to have static ip. + if user.HostID != 0 { + continue + } + + // Try the next available host id. + hostID := IP2HostID(network) + uint32(freeHostID) + for hostIDsContains(staticHostIDs, hostID+2) { + freeHostID++ // Increase the host id and try again until it is available. + hostID = IP2HostID(network) + uint32(freeHostID) } if user.ID == u.ID { - return HostID2IP(hostID) + return HostID2IP(hostID + 2) } + freeHostID++ } return nil } // GetIPNet returns user's vpn ip network. (e.g. 192.168.0.1/24) func (u *DBUser) GetIPNet() string { - mask := net.IPMask(net.ParseIP(_DefaultServerNetMask).To4()) + server, err := GetServerInstance() + if err != nil { + logrus.Panicf("can not get user ipnet: %v", err) + } + mask := net.IPMask(net.ParseIP(server.Mask).To4()) ipn := net.IPNet{ IP: u.getIP(), diff --git a/user_test.go b/user_test.go index a2a34a3..0e10e68 100644 --- a/user_test.go +++ b/user_test.go @@ -13,7 +13,7 @@ func TestCreateNewUser(t *testing.T) { // Initialize: ovpm.SetupDB("sqlite3", ":memory:") defer ovpm.CeaseDB() - ovpm.Init("localhost", "", ovpm.UDPProto) + ovpm.Init("localhost", "", ovpm.UDPProto, "") server, _ := ovpm.GetServerInstance() // Prepare: @@ -75,13 +75,21 @@ func TestCreateNewUser(t *testing.T) { if user.NoGW != noGW { t.Fatalf("user.NoGW is expected to be %t but it's %t instead", noGW, user.NoGW) } + + // Try to create a user with an invalid static ip. + user = nil + _, err = ovpm.CreateNewUser("staticuser", password, noGW, ovpm.IP2HostID(net.ParseIP("8.8.8.8").To4())) + if err == nil { + t.Fatalf("user creation expected to err but it didn't") + } + } func TestUserUpdate(t *testing.T) { // Initialize: ovpm.SetupDB("sqlite3", ":memory:") defer ovpm.CeaseDB() - ovpm.Init("localhost", "", ovpm.UDPProto) + ovpm.Init("localhost", "", ovpm.UDPProto, "") // Prepare: username := "testUser" @@ -97,16 +105,18 @@ func TestUserUpdate(t *testing.T) { var updatetests = []struct { password string noGW bool + hostid uint32 ok bool }{ - {"testpw", false, true}, - {"123", false, true}, - {"123", false, true}, - {"", true, true}, + {"testpw", false, 0, true}, + {"123", false, 0, true}, + {"123", false, 0, true}, + {"", true, 0, true}, + {"", true, ovpm.IP2HostID(net.ParseIP("10.10.10.10").To4()), false}, // Invalid static address. } for _, tt := range updatetests { - err := user.Update(tt.password, tt.noGW, 0) + err := user.Update(tt.password, tt.noGW, tt.hostid) if (err == nil) != tt.ok { t.Errorf("user is expected to be able to update but it gave us this error instead: %v", err) } @@ -117,7 +127,7 @@ func TestUserPasswordCorrect(t *testing.T) { // Initialize: ovpm.SetupDB("sqlite3", ":memory:") defer ovpm.CeaseDB() - ovpm.Init("localhost", "", ovpm.UDPProto) + ovpm.Init("localhost", "", ovpm.UDPProto, "") // Prepare: initialPassword := "g00dp@ssW0rd9" @@ -134,7 +144,7 @@ func TestUserPasswordReset(t *testing.T) { // Initialize: ovpm.SetupDB("sqlite3", ":memory:") defer ovpm.CeaseDB() - ovpm.Init("localhost", "", ovpm.UDPProto) + ovpm.Init("localhost", "", ovpm.UDPProto, "") // Prepare: initialPassword := "g00dp@ssW0rd9" @@ -161,7 +171,7 @@ func TestUserDelete(t *testing.T) { // Initialize: ovpm.SetupDB("sqlite3", ":memory:") defer ovpm.CeaseDB() - ovpm.Init("localhost", "", ovpm.UDPProto) + ovpm.Init("localhost", "", ovpm.UDPProto, "") // Prepare: username := "testUser" @@ -199,7 +209,7 @@ func TestUserGet(t *testing.T) { // Initialize: ovpm.SetupDB("sqlite3", ":memory:") defer ovpm.CeaseDB() - ovpm.Init("localhost", "", ovpm.UDPProto) + ovpm.Init("localhost", "", ovpm.UDPProto, "") // Prepare: username := "testUser" @@ -223,7 +233,7 @@ func TestUserGetAll(t *testing.T) { // Initialize: ovpm.SetupDB("sqlite3", ":memory:") defer ovpm.CeaseDB() - ovpm.Init("localhost", "", ovpm.UDPProto) + ovpm.Init("localhost", "", ovpm.UDPProto, "") count := 5 // Prepare: @@ -261,14 +271,14 @@ func TestUserRenew(t *testing.T) { // Initialize: ovpm.SetupDB("sqlite3", ":memory:") defer ovpm.CeaseDB() - ovpm.Init("localhost", "", ovpm.UDPProto) + ovpm.Init("localhost", "", ovpm.UDPProto, "") // Prepare: user, _ := ovpm.CreateNewUser("user", "1234", false, 0) // Test: // Re initialize the server. - ovpm.Init("example.com", "3333", ovpm.UDPProto) // This causes implicit Renew() on every user in the system. + ovpm.Init("example.com", "3333", ovpm.UDPProto, "") // This causes implicit Renew() on every user in the system. // Fetch user back. fetchedUser, _ := ovpm.GetUser(user.GetUsername()) @@ -283,7 +293,7 @@ func TestUserIPAllocator(t *testing.T) { // Initialize: ovpm.SetupDB("sqlite3", ":memory:") defer ovpm.CeaseDB() - ovpm.Init("localhost", "", ovpm.UDPProto) + ovpm.Init("localhost", "", ovpm.UDPProto, "") // Prepare: @@ -299,9 +309,8 @@ func TestUserIPAllocator(t *testing.T) { {"user2", false, 0, "10.9.0.3/24", true}, {"user3", true, 0, "10.9.0.4/24", true}, {"user4", true, ovpm.IP2HostID(net.ParseIP("10.9.0.5").To4()), "10.9.0.5/24", true}, - {"user5", true, ovpm.IP2HostID(net.ParseIP("192.168.1.1").To4()), "10.9.0.6/24", false}, {"user6", true, ovpm.IP2HostID(net.ParseIP("10.9.0.7").To4()), "10.9.0.7/24", true}, - {"user7", true, 0, "10.9.0.8/24", true}, + {"user7", true, 0, "10.9.0.6/24", true}, } for _, tt := range iptests { user, err := ovpm.CreateNewUser(tt.username, "pass", tt.gw, tt.hostid) @@ -310,7 +319,7 @@ func TestUserIPAllocator(t *testing.T) { } if user != nil { if user.GetIPNet() != tt.expectedIP { - t.Fatalf("%s is expected to be %s", user.GetIPNet(), tt.expectedIP) + t.Fatalf("user %s ip %s is expected to be %s", user.GetUsername(), user.GetIPNet(), tt.expectedIP) } } } diff --git a/vpn.go b/vpn.go index 8edf910..f888b23 100644 --- a/vpn.go +++ b/vpn.go @@ -69,10 +69,17 @@ type _VPNServerConfig struct { Proto string } -// Init regenerates keys and certs for a Root CA, and saves them in the database. +// Init regenerates keys and certs for a Root CA, gets initial settings for the VPN server +// and saves them in the database. // -// proto can be either "udp" or "tcp" and if it's "" it defaults to "udp". -func Init(hostname string, port string, proto string) error { +// 'proto' can be either "udp" or "tcp" and if it's "" it defaults to "udp". +// +// 'ipblock' is a IP network in the CIDR form. VPN clients get their IP addresses from this network. +// It defaults to const 'DefaultVPNNetwork'. +// +// Please note that, Init is potentially destructive procedure, it will cause invalidation of +// existing .ovpn profiles of the current users. So it should be used carefully. +func Init(hostname string, port string, proto string, ipblock string) error { if port == "" { port = DefaultVPNPort } @@ -88,6 +95,33 @@ func Init(hostname string, port string, proto string) error { return fmt.Errorf("validation error: proto:`%s` should be either 'tcp' or 'udp'", proto) } + // vpn network to use. + var ipnet *net.IPNet + + // If user didn't specify, pick the vpn network from defaults. + if ipblock == "" { + var err error + _, ipnet, err = net.ParseCIDR(DefaultVPNNetwork) + if err != nil { + return fmt.Errorf("can not parse CIDR %s: %v", DefaultVPNNetwork, err) + } + } + + // Check if the user specified vpn network is valid. + if ipblock != "" && !govalidator.IsCIDR(ipblock) { + return fmt.Errorf("validation error: ipblock:`%s` should be a CIDR network", ipblock) + } + + // Use user specified vpn network. + if ipblock != "" { + var err error + _, ipnet, err = net.ParseCIDR(ipblock) + if err != nil { + return fmt.Errorf("can parse ipblock: %s", err) + + } + } + if !govalidator.IsNumeric(port) { return fmt.Errorf("validation error: port:`%s` should be numeric", port) } @@ -113,6 +147,7 @@ func Init(hostname string, port string, proto string) error { if err != nil { return fmt.Errorf("can not create server cert creds: %s", err) } + serialNumber := uuid.New().String() serverInstance := DBServer{ Name: serverName, @@ -125,8 +160,8 @@ func Init(hostname string, port string, proto string) error { Key: srv.Key, CACert: ca.Cert, CAKey: ca.Key, - Net: _DefaultServerNetwork, - Mask: _DefaultServerNetMask, + Net: ipnet.IP.To4().String(), + Mask: net.IP(ipnet.Mask).To4().String(), } db.Create(&serverInstance) @@ -375,6 +410,11 @@ func emitToFile(path, content string, mode uint) error { } func emitServerConf() error { + dbServer, err := GetServerInstance() + if err != nil { + return fmt.Errorf("can not get server instance: %v", err) + } + serverInstance, err := GetServerInstance() if err != nil { return fmt.Errorf("can not retrieve server: %v", err) @@ -384,6 +424,11 @@ func emitServerConf() error { port = serverInstance.Port } + proto := DefaultVPNProto + if serverInstance.Proto != "" { + proto = serverInstance.Proto + } + var result bytes.Buffer server := _VPNServerConfig{ @@ -394,10 +439,10 @@ func emitServerConf() error { CCDPath: _DefaultVPNCCDPath, CRLPath: _DefaultCRLPath, DHParamsPath: _DefaultDHParamsPath, - Net: _DefaultServerNetwork, - Mask: _DefaultServerNetMask, + Net: dbServer.Net, + Mask: dbServer.Mask, Port: port, - Proto: serverInstance.Proto, + Proto: proto, } data, err := bindata.Asset("template/server.conf.tmpl") if err != nil { @@ -526,6 +571,11 @@ func emitCCD() error { } } } + server, err := GetServerInstance() + if err != nil { + return fmt.Errorf("can not get server instance: %v", err) + } + // Render ccd templates for the users. for _, user := range users { var associatedRoutes [][3]string @@ -550,7 +600,7 @@ func emitCCD() error { NetMask string Routes [][3]string // [0] is IP, [1] is Netmask, [2] is Via RedirectGW bool - }{IP: user.getIP().String(), NetMask: _DefaultServerNetMask, Routes: associatedRoutes, RedirectGW: !user.NoGW} + }{IP: user.getIP().String(), NetMask: server.Mask, Routes: associatedRoutes, RedirectGW: !user.NoGW} data, err := bindata.Asset("template/ccd.file.tmpl") if err != nil { diff --git a/vpn_test.go b/vpn_test.go index b90f847..e6b5e98 100644 --- a/vpn_test.go +++ b/vpn_test.go @@ -35,13 +35,13 @@ func TestVPNInit(t *testing.T) { } // Wrongfully initialize server. - err := Init("localhost", "asdf", UDPProto) + err := Init("localhost", "asdf", UDPProto, "") if err == nil { t.Fatalf("error is expected to be not nil but it's nil instead") } // Initialize the server. - Init("localhost", "", UDPProto) + Init("localhost", "", UDPProto, "") // Check database if the database has no server. var server2 DBServer @@ -61,7 +61,7 @@ func TestVPNDeinit(t *testing.T) { // Prepare: // Initialize the server. - Init("localhost", "", UDPProto) + Init("localhost", "", UDPProto, "") u, err := CreateNewUser("user", "p", false, 0) if err != nil { t.Fatal(err) @@ -122,7 +122,7 @@ func TestVPNIsInitialized(t *testing.T) { } // Initialize the server. - Init("localhost", "", UDPProto) + Init("localhost", "", UDPProto, "") // Isn't initialized? if !IsInitialized() { @@ -152,7 +152,7 @@ func TestVPNGetServerInstance(t *testing.T) { } // Initialize server. - Init("localhost", "", UDPProto) + Init("localhost", "", UDPProto, "") server, err = GetServerInstance() @@ -172,7 +172,7 @@ func TestVPNDumpsClientConfig(t *testing.T) { setupTestCase() SetupDB("sqlite3", ":memory:") defer CeaseDB() - Init("localhost", "", UDPProto) + Init("localhost", "", UDPProto, "") // Prepare: user, _ := CreateNewUser("user", "password", false, 0) @@ -194,7 +194,7 @@ func TestVPNDumpClientConfig(t *testing.T) { setupTestCase() SetupDB("sqlite3", ":memory:") defer CeaseDB() - Init("localhost", "", UDPProto) + Init("localhost", "", UDPProto, "") // Prepare: noGW := false @@ -262,7 +262,7 @@ func TestVPNGetSystemCA(t *testing.T) { } // Initialize system. - Init("localhost", "", UDPProto) + Init("localhost", "", UDPProto, "") ca, err = GetSystemCA() if err != nil { @@ -302,7 +302,7 @@ func TestVPNStartVPNProc(t *testing.T) { } // Initialize OVPM server. - Init("localhost", "", UDPProto) + Init("localhost", "", UDPProto, "") // Call start again.. StartVPNProc() @@ -318,7 +318,7 @@ func TestVPNStopVPNProc(t *testing.T) { setupTestCase() SetupDB("sqlite3", ":memory:") defer CeaseDB() - Init("localhost", "", UDPProto) + Init("localhost", "", UDPProto, "") // Prepare: vpnProc.Start() @@ -342,7 +342,7 @@ func TestVPNRestartVPNProc(t *testing.T) { // Init: SetupDB("sqlite3", ":memory:") defer CeaseDB() - Init("localhost", "", UDPProto) + Init("localhost", "", UDPProto, "") // Prepare: @@ -371,7 +371,7 @@ func TestVPNEmit(t *testing.T) { setupTestCase() SetupDB("sqlite3", ":memory:") defer CeaseDB() - Init("localhost", "", UDPProto) + Init("localhost", "", UDPProto, "") // Prepare: