From 0c531a30c254a140fbed4ea4f7d359a7811fa6a5 Mon Sep 17 00:00:00 2001 From: mgerb42 Date: Wed, 31 Aug 2016 17:46:05 +0000 Subject: [PATCH] new post - updated server directories --- package.json | 4 +- .../Web Stuff/2016-08-30-ubuntu16-mongodb.md | 206 ++++++++++++++++++ server/controller/redirect.go | 2 +- server/model/raw_sensor/raw_sensor.go | 53 +---- server.go => server/mywebsite.go | 16 -- server/utils/config.go | 2 +- 6 files changed, 213 insertions(+), 70 deletions(-) create mode 100644 posts/Web Stuff/2016-08-30-ubuntu16-mongodb.md rename server.go => server/mywebsite.go (66%) diff --git a/package.json b/package.json index e744041..2221191 100644 --- a/package.json +++ b/package.json @@ -7,8 +7,8 @@ "build": "webpack && babel-node metadata.js", "c9": "webpack-dev-server --port $PORT --host $IP --hot --content-base dist --history-api-fallback", "dev": "webpack-dev-server --content-base public --inline --hot --history-api-fallback", - "prod": "export NODE_ENV=production && webpack -p && babel-node metadata.js && go build", - "prod-win": "set NODE_ENV=production && webpack -p && babel-node metadata.js && go build", + "prod": "export NODE_ENV=production && webpack -p && babel-node metadata.js && go build ./server/mywebsite.go", + "prod-win": "set NODE_ENV=production && webpack -p && babel-node metadata.js && go build ./server/mywebsite.go", "deploy" : "npm run prod && ./mywebsite" }, "repository": { diff --git a/posts/Web Stuff/2016-08-30-ubuntu16-mongodb.md b/posts/Web Stuff/2016-08-30-ubuntu16-mongodb.md new file mode 100644 index 0000000..57b2997 --- /dev/null +++ b/posts/Web Stuff/2016-08-30-ubuntu16-mongodb.md @@ -0,0 +1,206 @@ +# Installing and setting up authentication with MongoDB on Ubuntu 16.04.1 + +I recently spun up a new virtual machine on Digital Ocean and I decided to try the latest version +of Ubuntu.. because why not? I wanted to just host a MongoDB instance because I was going to host my site on Google's App Engine. +Turns out Google blocks any outgoing requests that are not HTTP. +(This prevents the Go [MGO](https://godoc.org/gopkg.in/mgo.v2) driver from connecting) + +*** + +## Installing MongoDB + +Luckily Digital Ocean offers great documentation when it comes to installing software. They usually have guides +and tutorials that are fairly up to date. I first followed [this guide](https://www.digitalocean.com/community/tutorials/how-to-install-mongodb-on-ubuntu-16-04) +to get MongoDB installed. + +On previous versions of Ubuntu, MongoDB was installed as a service. Newer versions use Systemd to run the database. +Systemd uses different commands to check database statistics. + +The Systemd configuration is located in a few different places, but mine seems to work in the following directory. +Here the run command can be edited, although this probably does not need to be done +as most settings can be adjusted in the MongoDB config file. + +MongoDB systemd config +```bash + /lib/systemd/system/mongod.service +``` + +MongoDB config +```bash + /etc/mongod.conf +``` + +Service as well as systemd can be used to start and stop MongoDB. +These commands will do the same thing, which is nice. +```bash + sudo service mongod + sudo systemctl mongod +``` + +Although you can start, stop, and restart MongoDB with service and systemctl, +MongoDB does not show up when listing all services. +```bash + sudo service --status-all +``` + +Systemclt must now be used +```bash + sudo systemctl status +``` + +## Enabling security for external connections + +Any time a port is opened up for a MongoDB instance security precautions must be taken. +[There are thousands of MongoDB instances that are exposed to the internet.](http://www.securityweek.com/thousands-mongodb-databases-found-exposed-internet) +There are a few reasons for this. MongoDB is usually run on the same machine of web applications, +therefore the port it is running on should not be opened up at all. MongoDB can also be tricky to configure properly +and a system admin must know exactly what they are doing in making the database secure. Login credentials do not +even need to be set up if the port it is running on is not even open. As soon as that port is opened up, +unwanted guests can gain easy access, especially if it is running on the default port (27018). + +The first thing to do when running MongoDB for external access is to run it on a completely different port. +Why run it on the port where attackers know exactly what they are looking for? + +Security authentication must be enabled in the MongoDB config file. It is turned off by default. +Make sure to do this after creating user accounts or else access will be denied. + +## Creating user accounts + +Although this probably isn't the most secure thing to do, I start out by creating a root admin. +I do this because it allows me control over any database and it gives me easier access and power. +My database doesn't store any sensative information so I am okay with this. + +A root admin can be created by connecting to the server with the command `mongo` using the admin database. +```bash + mongo + use admin +``` + +Databases can also be listed +```bash + show dbs +``` + +Use the admin database and create a root user +```bash + db.createUser( + { + user: "admin", + pwd: "password", + roles: ["root"] + } + ) +``` + +Verify that the user was created +```bash + db.getUsers() +``` + +Lets go enable security +```bash + sudo nano /etc/mongod.conf +``` + +Uncomment `#security` by removing the `#` and add this line after +```bash + security: + authorization: enabled +``` + +Restart database or reboot the system +```bash + sudo systemctl restart mongod +``` + +We can now authenticate to the database as our newly created root admin +```bash + mongo admin --port 27017 -u 'admin' -p 'password' +``` + +## Difficulties configuring users + +When I first started setting up users I had a heck of a time. I wasn't sure which database to use for certain +users or what permissions I had to give them. Part of this is due to my impatience of not reading the +documentation thoroughly. + +Server wide users/admins MUST be in the admin database. We created a root use in the admin database +previously so that user should have access to any database in the server. All database users must be in +their respective database. For example if we want to use the "test" database, users must be created +within this database in order to gain access. Although access can be gained with a root admin account, +this is something that should not be done in production. + +Lets create a read/write user for the "test" database +```bash + use test + + db.createUser( + { + user: "user", + pwd: "password", + roles: ["readWrite"] + } + ) +``` + +Verify that the user was created +```bash + db.getUsers() +``` + +Login as this user +```bash + mongo test --port 27017 -u 'user' -p 'admin' +``` + +Now a proper user should be set up for read/write access. This is the exact method I used to +gain access to an external database the Go's MGO MongoDB database driver. + +### Scripts for easier access to the database + +I created some shell scripts on my database server with credentials saved because I use long random passwords +that I cannot remember off the top of my head. (keep in mind this increases security risks) +It took me awhile to get this to work because some syntax did not work for me when inside of a shell script. + +I created a file called `mongo_admin.sh` and one called `mongo_user.sh`. + +The files look like this +```bash + mongo admin --port 27017 -u 'user' -p 'password' +``` + +This was frustrating because I figured out it would not work when using double quotes +inside of the shell script, although double quotes work when issuing the command manually. +I also realized that a database must be specified in order to connect. This can be done +like above, or like this. +```bash + mongo --port 27017 -u 'user' -p 'password' --authenticationDatabase admin +``` + +## Firewall + +Firewall rules must be changed to enable external database access. First of all, edit the MongoDB config +file and change the default database port. Once that is changed use [UFW](https://help.ubuntu.com/community/UFW) +to change firewall rules. For this example I will change MongoDB to run on port 27018. + +```bash + ufw enable + ufw status + ufw allow 27018/tcp +``` + +This will allow all incoming connections to the database. It is advised to only allow +incoming connections from the web application server that is being used. + +Allow to certain ip +```bash + ufw allow from to any port 27018 +``` + +## Conclusion + +MongoDB can be tricky to set up, but it is highly recommened to go through the entire process. +In the end I decided not to host my MongoDB instance externally so I did not go through +the entire [MongoDB security check list](https://docs.mongodb.com/v2.6/administration/security-checklist/#audit-system-activity). +There are a few other things to do such as adding encryption and monitoring system activity, but +I covered most of the important issues. \ No newline at end of file diff --git a/server/controller/redirect.go b/server/controller/redirect.go index 0b78f0f..35299bd 100644 --- a/server/controller/redirect.go +++ b/server/controller/redirect.go @@ -11,7 +11,7 @@ func DiscordRedirect(w http.ResponseWriter, r *http.Request, _ httprouter.Params http.Redirect(w, r, "https://discordapp.com/invite/0Z2tzxKECEj2BHwj", 301) } -// Redirect to discord +// Redirect to vpn func VPNRedirect(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { http.Redirect(w, r, "https://mitchel.io:943", 301) } diff --git a/server/model/raw_sensor/raw_sensor.go b/server/model/raw_sensor/raw_sensor.go index c329a09..9b91b54 100644 --- a/server/model/raw_sensor/raw_sensor.go +++ b/server/model/raw_sensor/raw_sensor.go @@ -34,6 +34,7 @@ func (s *Data) toJson() string { } +//default store structure func (s *Data) StoreData() error { if db.Mongo.Connected() { @@ -57,13 +58,13 @@ func (s *Data) StoreData() error { } //handle queries for all sensors page -//******************************************************************************** type DataStore_AllSensors struct { ID string `json:"location" bson:"_id"` Temperature float64 `json:"temperature" bson:"temperature"` Updated time.Time `json:"updated" bson:"updated"` } +//get latest update from each unique sensor func GetAllSensors() ([]DataStore_AllSensors, error) { s := []DataStore_AllSensors{} @@ -88,52 +89,4 @@ func GetAllSensors() ([]DataStore_AllSensors, error) { } else { return s, errors.New("Query failed") } -} - -//******************************************************************************** - -//get sensor information by location -//******************************************************************************** -type DataStore_SensorByLocation struct { - Id sensorByLocation `json:"_id" bson:"_id"` -} - -type sensorByLocation struct { - Year int `json:"year" bson:"year"` - Month int `json:"month" bson:"month"` - Location string `json:"location" bson:"location"` -} - -/* -func GetSensorInfoByLocation(sensor_location string) ([]DataStore_SensorByLocation, error) { - s := []DataStore_SensorByLocation{} - if db.Mongo.Connected() == true { - session := db.Mongo.Session.Copy() - defer session.Close() - c := session.DB(db.Mongo.Info.Database).C(collection) - err := c.Pipe([]bson.M{{"$project": bson.M{"location": "$location", "year": bson.M{"$year": "$updated"}, "month": bson.M{"$month": "$updated"}}}, - bson.M{"$match": bson.M{"location": sensor_location}}, - bson.M{"$group": bson.M{"_id": bson.M{"year": "$year", "month": "$month", "location": "$location"}}}, - bson.M{"$sort": bson.M{"_id.year": -1, "_id.month": -1}}}).All(&s) - if err != nil { - log.Println(err) - return s, nil - } - return s, nil - } else { - return s, errors.New("Query failed") - } -} -*/ - -//******************************************************************************** - -/************************* -testStore := model.SensorData{ - ID: bson.NewObjectId(), - Temperature: 34.2, - Humidity: 33.22, - Location: "Grand Meadow", - Updated: time.Now(), -} -**************************/ +} \ No newline at end of file diff --git a/server.go b/server/mywebsite.go similarity index 66% rename from server.go rename to server/mywebsite.go index 6199475..edb23b2 100644 --- a/server.go +++ b/server/mywebsite.go @@ -6,28 +6,12 @@ import ( "strconv" "github.com/NYTimes/gziphandler" - //local import paths relative to app.yaml file "mywebsite/server/controller/api" "mywebsite/server/db" "mywebsite/server/route" "mywebsite/server/utils" ) -/* for app engine -func init() { - configurations := utils.ReadConfig() - - db.Configure(configurations.Database) - api.Configure(configurations.Api) - - db.Mongo.Connect() - - router := route.Routes() - - http.Handle("/", router) -} -*/ - func main(){ configurations := utils.ReadConfig() diff --git a/server/utils/config.go b/server/utils/config.go index 4b60f40..e6b45b8 100644 --- a/server/utils/config.go +++ b/server/utils/config.go @@ -14,7 +14,7 @@ import ( type Config struct { Database db.DatabaseInfo `json:"database"` Api api.ApiInfo `json:"api"` - Port int `json:"port"` + Port int `json:"port"` } //read the config file and return JsonObject struct