Merge branch 'master' into add_docker_compose

This commit is contained in:
Brandon Myers 2017-08-04 15:09:26 -05:00 коммит произвёл GitHub
Родитель e1ede7c055 f31f048869
Коммит 58081ac415
12 изменённых файлов: 284 добавлений и 390 удалений

Просмотреть файл

@ -3,10 +3,11 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
# Copyright (c) 2014 Mozilla Corporation
# Copyright (c) 2017 Mozilla Corporation
#
# Contributors:
# Jeff Bryner jbryner@mozilla.com
# Brandon Myers bmyers@mozilla.com
from lib.alerttask import AlertTask
from query_models import SearchQuery, TermMatch, PhraseMatch, WildcardMatch
@ -19,19 +20,18 @@ class AlertAccountCreations(AlertTask):
search_query.add_must([
TermMatch('_type', 'event'),
TermMatch('tags', 'firefoxaccounts'),
PhraseMatch('details.path', '/v1/account/create')
PhraseMatch('details.action', 'accountCreate')
])
# ignore test accounts and attempts to create accounts that already exist.
search_query.add_must_not([
WildcardMatch('details.email', '*restmail.net'),
TermMatch('details.code', '429')
])
self.filtersManual(search_query)
# Search aggregations on field 'sourceipv4address', keep X samples of events at most
self.searchEventsAggregated('details.sourceipv4address', samplesLimit=10)
# Search aggregations on field 'ip', keep X samples of events at most
self.searchEventsAggregated('details.ip', samplesLimit=10)
# alert when >= X matching events in an aggregation
self.walkAggregations(threshold=10)

Просмотреть файл

@ -1,4 +0,0 @@
[options]
smtpserver = <add_smtpserver>
sender = <add_sender_email>
recipients = <add_recipient_email>,<add_recipient2_email>

Просмотреть файл

@ -1,73 +0,0 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
# Copyright (c) 2017 Mozilla Corporation
#
# Contributors:
# Alicia Smith <asmith@mozilla.com>
# Michal Purzynski <mpurzynski@mozilla.com>
# Brandon Myers <bmyers@mozilla.com>
import os
import sys
from datetime import datetime
from configlib import getConfig, OptionParser
import smtplib
from email.mime.text import MIMEText
from email.Utils import formatdate
from time import mktime
class message(object):
def __init__(self):
'''
takes an incoming alert
and uses it to trigger an email sent to
the releng signing server team
'''
self.registration = ['access']
self.priority = 2
# set my own conf file
# relative path to the alerts alertWorker.py file
self.configfile = './plugins/ssh_access_signreleng.conf'
self.options = None
if os.path.exists(self.configfile):
sys.stdout.write('found conf file {0}\n'.format(self.configfile))
self.initConfiguration()
def initConfiguration(self):
myparser = OptionParser()
# setup self.options by sending empty list [] to parse_args
(self.options, args) = myparser.parse_args([])
# email settings
self.options.smtpserver = getConfig('smtpserver', 'localhost', self.configfile)
self.options.sender = getConfig('sender', 'donotreply@localhost.com', self.configfile)
recipients_str = getConfig('recipients', 'noone@localhost.com', self.configfile)
self.options.recipients = recipients_str.split(',')
def onMessage(self, message):
# here is where you do something with the incoming alert message
emailMessage = MIMEText(message['summary'] + ' on ' + message['events'][0]['documentsource']['utctimestamp'])
emailMessage['Subject'] = 'MozDef Alert: Releng Restricted Servers Successful SSH Access'
emailMessage['From'] = self.options.sender
emailMessage['To'] = ','.join(self.options.recipients)
nowtuple = mktime(datetime.utcnow().timetuple())
# The Date field needs to be in a specific format, and we must
# define it or gmail struggles to parse it.
emailMessage['Date'] = formatdate(nowtuple)
smtpObj = smtplib.SMTP(self.options.smtpserver, 25)
try:
smtpObj.sendmail(self.options.sender, self.options.recipients, emailMessage.as_string())
smtpObj.quit()
except smtplib.SMTPException as e:
sys.stderr.write('Error: failed to send email {0}\n'.format(e))
# you can modify the message if needed
# plugins registered with lower (>2) priority
# will receive the message and can also act on it
# but even if not modified, you must return it
return message

Просмотреть файл

@ -192,16 +192,18 @@ Marvel plugin
`Marvel`_ is a monitoring plugin developed by Elasticsearch (the company).
WARNING: this plugin is NOT open source. At the time of writing, Marvel is free for development but you have to get a license for production.
WARNING: this plugin is NOT open source. At the time of writing, Marvel is free for 30 days.
After which you can apply for a free basic license to continue using it for it's key monitoring features.
To install Marvel, on each of your elasticsearch node, from the Elasticsearch home directory::
sudo bin/plugin -i elasticsearch/marvel/latest
sudo bin/plugin install license
sudo bin/plugin install marvel-agent
sudo service elasticsearch restart
You should now be able to access to Marvel at http://any-server-in-cluster:9200/_plugin/marvel
.. _Marvel: http://www.elasticsearch.org/overview/marvel/
.. _Marvel: https://www.elastic.co/guide/en/marvel/current/introduction.html
Web and Workers nodes
---------------------
@ -228,9 +230,9 @@ On APT-based systems::
Then::
su - mozdef
wget http://python.org/ftp/python/2.7.6/Python-2.7.6.tgz
tar xvzf Python-2.7.6.tgz
cd Python-2.7.6
wget https://www.python.org/ftp/python/2.7.11/Python-2.7.11.tgz
tar xvzf Python-2.7.11.tgz
cd Python-2.7.11
./configure --prefix=/opt/mozdef/python2.7 --enable-shared
make
make install
@ -247,7 +249,7 @@ Then::
source mozdef/bin/activate
pip install -r MozDef/requirements.txt
At this point when you launch python, It should tell you that you're using Python 2.7.6.
At this point when you launch python, It should tell you that you're using Python 2.7.11.
Whenever you launch a python script from now on, you should have your mozdef virtualenv actived and your LD_LIBRARY_PATH env variable should include /opt/mozdef/python2.7/lib/
@ -256,14 +258,21 @@ RabbitMQ
`RabbitMQ`_ is used on workers to have queues of events waiting to be inserted into the Elasticsearch cluster (storage).
RabbitMQ does provide a zero-dependency RPM that you can find for RedHat/CentOS here::
https://github.com/rabbitmq/erlang-rpm
For Debian/Ubuntu based distros you would need to install erlang separately.
To install it, first make sure you enabled `EPEL repos`_. Then you need to install an Erlang environment.
If you prefer to install all the dependencies on a Red Hat based system you can do the following::
On Yum-based systems::
sudo yum install erlang
You can then install the rabbitmq server::
sudo rpm --import http://www.rabbitmq.com/rabbitmq-signing-key-public.asc
sudo rpm --import https://www.rabbitmq.com/rabbitmq-signing-key-public.asc
sudo yum install rabbitmq-server
To start rabbitmq at startup::
@ -307,34 +316,52 @@ For meteor, in a terminal::
curl https://install.meteor.com/ | sh
wget http://nodejs.org/dist/v0.10.26/node-v0.10.26.tar.gz
tar xvzf node-v0.10.26.tar.gz
cd node-v0.10.26
wget https://nodejs.org/dist/v4.7.0/node-v4.7.0.tar.gz
tar xvzf node-v4.7.0.tar.gz
cd node-v4.7.0
./configure
make
sudo make install
Make sure you have meteorite/mrt (run as root/admin)::
npm install -g meteorite
Then from the meteor subdirectory of this git repository (/opt/mozdef/MozDef/meteor) run::
mrt add iron-router
mrt add accounts-persona
meteor add iron-router
You may want to edit the app/lib/settings.js file to properly point to your elastic search server::
If you wish to use meteor as the authentication handler you'll also need to install the Accounts-Password pkg::
meteor add accounts-password
elasticsearch={
address:"http://servername:9200/",
healthurl:"_cluster/health",
docstatsurl:"_stats/docs"
}
You may want to edit the app/lib/settings.js file to properly configure the URLs and Authentication
The default setting will use Meteor Accounts, but you can just as easily install an external provider like Github, Google, Facebook or your own OIDC::
mozdef = {
rootURL: "localhost",
port: "443",
rootAPI: "https://localhost:8444",
kibanaURL: "https://localhost:9443/app/kibana#",
enableBlockIP: true,
enableClientAccountCreation: true,
authenticationType: "meteor-password"
}
or for an OIDC implementation that passes a header to the nginx reverse proxy (for example using OpenResty with Lua and Auth0)::
mozdef = {
rootURL: "localhost",
port: "443",
rootAPI: "https://localhost:8444",
kibanaURL: "https://localhost:9443/app/kibana#",
enableBlockIP: true,
enableClientAccountCreation: false,
authenticationType: "OIDC"
}
Then start meteor with::
meteor
.. _meteor: https://guide.meteor.com/
.. _meteor-accounts: https://guide.meteor.com/accounts.html
Node
******
@ -344,9 +371,9 @@ Alternatively you can run the meteor UI in 'deployment' mode using a native node
First install node::
yum install bzip2 gcc gcc-c++ sqlite sqlite-devel
wget http://nodejs.org/dist/v0.10.25/node-v0.10.25.tar.gz
tar xvfz node-v0.10.25.tar.gz
cd node-v0.10.25
wget https://nodejs.org/dist/v4.7.0/node-v4.7.0.tar.gz
tar xvfz node-v4.7.0.tar.gz
cd node-v4.7.0
python configure
make
make install
@ -363,7 +390,7 @@ You can then deploy the meteor UI for mozdef as necessary::
This will create a 'bundle' directory with the entire UI code below that directory.
You will need to update the settings.js file to match your servername/port::
If you didn't update the settings.js before bundling the meteor installation, you will need to update the settings.js file to match your servername/port::
vim bundle/programs/server/app/app/lib/settings.js
@ -374,7 +401,8 @@ the fibers node module::
rm -rf fibers
sudo npm install fibers@1.0.1
Then run the mozdef UI via node::
There are systemd unit files available in the systemd directory of the public repo you can use to start meteor using node.
If you aren't using systemd, then run the mozdef UI via node manually::
export MONGO_URL=mongodb://mongoservername:3002/meteor
export ROOT_URL=http://meteorUIservername/
@ -400,11 +428,11 @@ On apt-get based system::
If you don't have this package in your repos, before installing create `/etc/yum.repos.d/nginx.repo` with the following content::
[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/centos/6/$basearch/
gpgcheck=0
enabled=1
[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/OS/OSRELEASE/$basearch/
gpgcheck=0
enabled=1
.. _nginx: http://nginx.org/
@ -413,9 +441,9 @@ UWSGI
We use `uwsgi`_ to interface python and nginx::
wget http://projects.unbit.it/downloads/uwsgi-2.0.2.tar.gz
tar zxvf uwsgi-2.0.2.tar.gz
cd uwsgi-2.0.2
wget https://projects.unbit.it/downloads/uwsgi-2.0.12.tar.gz
tar zxvf uwsgi-2.0.12.tar.gz
cd uwsgi-2.0.12
~/python2.7/bin/python uwsgiconfig.py --build
~/python2.7/bin/python uwsgiconfig.py --plugin plugins/python core
cp python_plugin.so ~/envs/mozdef/bin/
@ -442,16 +470,16 @@ We use `uwsgi`_ to interface python and nginx::
sudo vim /etc/nginx/nginx.conf
sudo service nginx restart
.. _uwsgi: http://projects.unbit.it/uwsgi/
.. _uwsgi: https://uwsgi-docs.readthedocs.io/en/latest/
Kibana
******
`Kibana`_ is a webapp to visualize and search your Elasticsearch cluster data::
wget https://download.elasticsearch.org/kibana/kibana/kibana-3.0.0milestone5.tar.gz
tar xvzf kibana-3.0.0milestone5.tar.gz
mv kibana-3.0.0milestone5 kibana
wget https://download.elastic.co/kibana/kibana/kibana-4.6.2-linux-x86_64.tar.gz
tar xvzf kibana-4.6.2-linux-x86_64.tar.gz
ln -s kibana-4.6.2 kibana
# configure /etc/nginx/nginx.conf to target this folder
sudo service nginx reload
@ -460,11 +488,13 @@ To initialize elasticsearch indices and load some sample data::
cd examples/es-docs/
python inject.py
.. _Kibana: http://www.elasticsearch.org/overview/kibana
.. _Kibana: https://www.elastic.co/products/kibana
Start Services
**************
TO DO: Add in services like supervisord, and refer to systemd files.
Start the following services
cd ~/MozDef/mq
@ -541,21 +571,22 @@ Manual Installation
6. Installing Kibana ::
$ cd /tmp/
$ curl -L https://download.elasticsearch.org/kibana/kibana/kibana-3.1.0.tar.gz | tar -C /opt -xz
$ /bin/ln -s /opt/kibana-3.1.0 /opt/kibana
$ curl -L https://download.elastic.co/kibana/kibana/kibana-4.6.2-linux-x86_64.tar.gz | tar -C /opt -xz
$ /bin/ln -s /opt/kibana-4.6.2 /opt/kibana
$ cp $MOZDEF_PATH/examples/kibana/dashboards/alert.js /opt/kibana/app/dashboards/alert.js
$ cp $MOZDEF_PATH/examples/kibana/dashboards/event.js /opt/kibana/app/dashboards/event.js
7. Installing Elasticsearch ::
$ wget https://gist.githubusercontent.com/yashmehrotra/3209a7e2c696c2ac5110/raw/9161ffb32ee79d48f4bce224f8710ac8c7e85922/ElasticSearch.sh
# You can download any version of ELasticSearch
$ ./ElasticSearch.sh 1.6.0
For Red Hat based:
$ wget https://download.elastic.co/elasticsearch/release/org/elasticsearch/distribution/rpm/elasticsearch/2.4.5/elasticsearch-2.4.5.rpm
For Debian based:
$ wget https://download.elastic.co/elasticsearch/release/org/elasticsearch/distribution/deb/elasticsearch/2.4.5/elasticsearch-2.4.5.deb
# You can download and install any version of ELasticSearch > 2.x and < 5.x
8. Setting up Meteor ::
$ curl -L https://install.meteor.com/ | /bin/sh
$ npm install -g meteorite
$ cd $MOZDEF_PATH/meteor
$ meteor

Просмотреть файл

@ -1,9 +0,0 @@
# beaver-syslog
This configuration for [beaver](https://github.com/josegonzalez/beaver) ships syslog logs stored in `/var/log/syslog/systems/myhost.example.com/*.log` to mozdef.
To run it:
```
beaver -c config.ini -t stdout
```

Двоичные данные
examples/beaver-syslog/config.ini

Двоичный файл не отображается.

Просмотреть файл

@ -9,6 +9,7 @@ Jeff Bryner jbryner@mozilla.com
Anthony Verez averez@mozilla.com
Yash Mehrotra yashmehrotra95@gmail.com
Avijit Gupta 526avijit@gmail.com
Alicia Smith asmith@mozilla.com
*/
if (Meteor.isClient) {
@ -25,10 +26,10 @@ if (Meteor.isClient) {
Session.set('attackerlimit','10');
getAllPlugins();
//assumes connection to an nginx/apache front end
//serving up an site handling authentication set via
//server side header
Meteor.loginViaHeader();
// Sends us to register our login handler
// and then to the login function of choice
// based on how enableClientAccountCreation was set at deployment.
Meteor.login();
//see if we have a myo armband
try{
@ -369,7 +370,27 @@ if (Meteor.isClient) {
}
});
//sample login function
// login abstraction
Meteor.login = function(callback) {
var authenticationType = mozdef.authenticationType;
switch(authenticationType){
case 'meteor-password':
Meteor.loginViaPassword(callback);
break;
case 'oidc':
Meteor.loginViaHeader(callback);
break;
default:
// non-breaking default of header
// todo: evaluate defaulting to meteor-password
Meteor.loginViaHeader(callback);
break;
}
}
//assumes connection to an nginx/apache front end
//serving up an site handling authentication set via
//server side header
Meteor.loginViaHeader = function(callback) {
//create a login request to pass to loginHandler
var loginRequest = {};
@ -380,4 +401,8 @@ if (Meteor.isClient) {
});
};
Meteor.loginViaPassword = function(callback) {
// noop - allow meteor to pass through
};
};

Просмотреть файл

@ -8,6 +8,7 @@ Contributors:
Jeff Bryner jbryner@mozilla.com
Anthony Verez averez@mozilla.com
Brandon Myers bmyers@mozilla.com
Alicia Smith asmith@mozilla.com
*/
//configuration settings
@ -18,6 +19,7 @@ mozdef = {
rootAPI: "https://localhost:8444",
kibanaURL: "https://localhost:9443/app/kibana#",
enableBlockIP: true,
enableClientAccountCreation: false
enableClientAccountCreation: true,
authenticationType: "meteor-password"
}

Просмотреть файл

@ -7,13 +7,14 @@ Copyright (c) 2014 Mozilla Corporation
Contributors:
Jeff Bryner jbryner@mozilla.com
Anthony Verez averez@mozilla.com
Alicia Smith asmith@mozilla.com
*/
if (Meteor.isServer) {
Meteor.startup(function () {
// Since we only connect to localhost or to ourselves, adding a hack to bypass cert validation
process.env.NODE_TLS_REJECT_UNAUTHORIZED="0";
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
console.log("MozDef starting")
//important to set this so persona can validate the source request
@ -27,82 +28,180 @@ if (Meteor.isServer) {
//Pull in settings.js entries into a collection
//so the client gets dynamic content
mozdefsettings.remove({});
mozdefsettings.insert({ key:'rootURL',
value : mozdef.rootURL + ':' + mozdef.port });
mozdefsettings.insert({ key:'rootAPI',
value : mozdef.rootAPI });
mozdefsettings.insert({ key:'kibanaURL',
value : mozdef.kibanaURL });
mozdefsettings.insert({ key:'enableBlockIP',
value : mozdef.enableBlockIP });
mozdefsettings.insert({
key: 'rootURL',
value: mozdef.rootURL + ':' + mozdef.port
});
mozdefsettings.insert({
key: 'rootAPI',
value: mozdef.rootAPI
});
mozdefsettings.insert({
key: 'kibanaURL',
value: mozdef.kibanaURL
});
mozdefsettings.insert({
key: 'enableBlockIP',
value: mozdef.enableBlockIP
});
//allow local account creation?
//http://docs.meteor.com/#/full/accounts_config
mozdefsettings.insert({ key:'enableClientAccountCreation',
value : mozdef.enableClientAccountCreation || false});
Accounts.registerLoginHandler("headerLogin",function(loginRequest) {
//there are multiple login handlers in meteor.
//a login request go through all these handlers to find it's login hander
//so in our login handler, we only consider login requests which are via a header
var self=this;
var sessionData = self.connection || (self._session ? self._session.sessionData : self._sessionData);
var session = Meteor.server.sessions[self.connection.id];
//ideally we would use a header unique to the installation like HTTP_OIDC_CLAIM_ID_TOKEN_EMAIL
//however sockJS whitelists only certain headers
// https://github.com/sockjs/sockjs-node/blob/8b03b3b1e7be14ee5746847f517029cb3ce30ca7/src/transport.coffee#L132
// choose one that is passed on and set it in your http server config:
var headerName='via';
console.log('connection headers',this.connection.httpHeaders);
console.log('target header:',this.connection.httpHeaders[headerName]);
//our authentication logic
//check for user email header
if(this.connection.httpHeaders[headerName] == undefined) {
console.log('refused login request due to missing http header')
return null;
}
console.log('handling login request',loginRequest);
//grab the email from the header
var userEmail = this.connection.httpHeaders[headerName];
//we create a user if needed, and get the userId
var userId = null;
var user = Meteor.users.findOne({profile:{email:userEmail}});
if(!user) {
console.log('creating user:',userEmail)
userId = Meteor.users.insert({
profile: { email: userEmail},
username: userEmail,
emails: [{address:userEmail , "verified": true}],
createdAt: new Date()
});
} else {
userId = user._id;
}
//generate login tokens
var stampedToken = Accounts._generateStampedLoginToken();
var hashStampedToken = Accounts._hashStampedToken(stampedToken);
//console.log(stampedToken,hashStampedToken);
//send loggedin user's user id
return {
userId: userId
}
var enableClientAccountCreation = !!(mozdef.enableClientAccountCreation || false);
Accounts._options.enableClientAccountCreation = enableClientAccountCreation;
mozdefsettings.insert({
key: 'enableClientAccountCreation',
value: enableClientAccountCreation
});
// newer meteor uses a key of forbidClientAccountCreation, so
// we negate the enableClientAccountCreation mozdef setting
Accounts._options.forbidClientAccountCreation = !enableClientAccountCreation;
mozdefsettings.insert({
key: 'forbidClientAccountCreation',
value: !!!enableClientAccountCreation
});
registerLoginMethod();
//update veris if missing:
console.log("checking the veris framework reference enumeration");
console.log('tags: ' + veris.find().count());
if (veris.find().count()==0) {
if (veris.find().count() == 0) {
console.log("updating the veris collection");
var verisFile = Assets.getText("veris.dotformat.txt");
var verisObject = verisFile.split("\n");
verisObject.forEach(function(verisItem) {
veris.insert({tag: verisItem});
verisObject.forEach(function (verisItem) {
veris.insert({ tag: verisItem });
});
}
}); //end startup
}); //end startup
} //end is server
function registerLoginMethod() {
// Setup a single login method to allow
var authenticationType = mozdef.authenticationType;
console.log("Authentication Type: ", authenticationType);
switch (authenticationType) {
case 'meteor-password':
registerLoginViaPassword();
break;
case 'oidc':
registerLoginViaHeader();
break;
default:
// non-breaking default of header
// todo: evaluate defaulting to meteor-password
registerLoginViaHeader();
break;
}
}
function registerLoginViaPassword() {
console.log("Setting up Password Authentication");
// We need to attach the users email address to the user.profile
Accounts.onCreateUser(function (options, user) {
if (user.emails.count <= 0) {
console.log("No user emails")
return user;
}
var email = user.emails[0].address;
if (typeof (email) === "undefined") {
console.log("User Email address not defined.")
return user;
}
if (typeof (user.profile) === "undefined") {
// user has no profile - this is the usual case
user.profile = {
"email": email
};
} else {
// overwrite any email that may be attached
// to the current user profile. this should
// not happen as we are currently creating
// the user.
user.profile['email'] = email;
}
// set any other profile information here.
return user
});
}
function registerLoginViaHeader() {
Accounts.registerLoginHandler("headerLogin", function (loginRequest) {
//there are multiple login handlers in meteor.
//a login request go through all these handlers to find it's login hander
//so in our login handler, we only consider login requests which are via a header
var self = this;
var sessionData = self.connection || (self._session ? self._session.sessionData : self._sessionData);
// TODO: Figure out where the bug is (probably sessionData as it is never used)
// There is either a bug here, assigning the session, or a bug when assigning sessionData. One of these can not ever happen.
var session = Meteor.server.sessions[self.connection.id];
//ideally we would use a header unique to the installation like HTTP_OIDC_CLAIM_ID_TOKEN_EMAIL
//however sockJS whitelists only certain headers
// https://github.com/sockjs/sockjs-node/blob/8b03b3b1e7be14ee5746847f517029cb3ce30ca7/src/transport.coffee#L132
// choose one that is passed on and set it in your http server config:
var headerName = 'via';
// Logging httpHeaders is possibly leaking sensitive data
console.log('connection headers', this.connection.httpHeaders);
//grab the email from the header
var userEmail = this.connection.httpHeaders[headerName];
//our authentication logic
//check for user email header
if (userEmail == undefined) {
console.log('refused login request due to missing http header')
// throw
return new {
error: handleError("SSO Login failure: email not found")
};
}
console.log('target header:', userEmail);
console.log('handling login request', loginRequest);
//we create a user if needed, and get the userId
var userId = null;
var user = Meteor.users.findOne({ profile: { email: userEmail } });
if (user) {
userId = user._id;
} else {
console.log('creating user:', userEmail)
userId = Meteor.users.insert({
profile: { email: userEmail },
username: userEmail,
emails: [{ address: userEmail, "verified": true }],
createdAt: new Date()
});
}
//generate login tokens
var stampedToken = Accounts._generateStampedLoginToken();
var hashStampedToken = Accounts._hashStampedToken(stampedToken);
//console.log(stampedToken,hashStampedToken);
//send loggedin user's user id
return {
userId: userId
}
});
}
function handleError(msg) {
const error = new Meteor.Error(
403,
Accounts._options.ambiguousErrorMessages
? "Login failure. Please check your login credentials."
: msg
);
return error;
}

Просмотреть файл

@ -33,13 +33,14 @@ class message(object):
'fxaoauthwebserver',
'fxabrowseridwebserver',
'fxaprofilewebserver',
'fxa-auth-server'
'fxa-auth-server',
'fxa-customsmozsvc'
]
self.priority = 10
def onMessage(self, message, metadata):
#drop non-relevant messages
if message['eventsource'] in ('FxaContentWebserver', 'FxaAuthWebserver', 'FxaOauthWebserver', 'FxaAuth', 'fxa-auth-server'):
if message['eventsource'] in ('Fxa-customsMozSvc', 'FxaContentWebserver', 'FxaAuthWebserver', 'FxaOauthWebserver', 'FxaAuth', 'fxa-auth-server'):
if 'details' in message.keys():
if 'status' in message['details']:
if message['details']['status'] == 200:

Просмотреть файл

@ -1,5 +0,0 @@
[options]
region=<add_region>
aws_access_key_id=<add_aws_access_key_id>
aws_secret_access_key=<add_aws_secret_access_key>
aws_queue_name=<add_aws_queue_name>

Просмотреть файл

@ -1,173 +0,0 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
# Copyright (c) 2014 Mozilla Corporation
#
# Contributors:
# Jeff Bryner jbryner@mozilla.com
import os
import sys
from configlib import getConfig, OptionParser
from datetime import datetime, timedelta
import json
import netaddr
import boto.sqs
from boto.sqs.message import RawMessage
def isIPv4(ip):
try:
# netaddr on it's own considers 1 and 0 to be valid_ipv4
# so a little sanity check prior to netaddr.
# Use IPNetwork instead of valid_ipv4 to allow CIDR
if '.' in ip and len(ip.split('.'))==4:
# some ips are quoted
netaddr.IPNetwork(ip.strip("'").strip('"'))
return True
else:
return False
except:
return False
def isIPv6(ip):
try:
return netaddr.valid_ipv6(ip)
except:
return False
class message(object):
def __init__(self):
'''register our criteria for being passed a message
as a list of lower case strings to match with an rest endpoint
(i.e. blockip matches /blockip)
set the priority if you have a preference for order of plugins
0 goes first, 100 is assumed/default if not sent
Plugins will register in Meteor with attributes:
name: (as below)
description: (as below)
priority: (as below)
file: "plugins.filename" where filename.py is the plugin code.
Plugin gets sent main rest options as:
self.restoptions
self.restoptions['configfile'] will be the .conf file
used by the restapi's index.py file.
'''
self.registration = ['blockip']
self.priority = 10
self.name = "fxaCustomsServer"
self.description = "Firefox Accounts SQS Queue"
# set my own conf file
# relative path to the rest index.py file
self.configfile = './plugins/fxaCustomsServer.conf'
self.options = None
if os.path.exists(self.configfile):
sys.stdout.write('found conf file {0}\n'.format(self.configfile))
self.initConfiguration()
def initConfiguration(self):
myparser = OptionParser()
# setup self.options by sending empty list [] to parse_args
(self.options, args) = myparser.parse_args([])
# fill self.options with plugin-specific options
# boto options
self.options.region = getConfig('region',
'us-west-2',
self.configfile)
self.options.aws_access_key_id=getConfig('aws_access_key_id',
'',
self.configfile)
self.options.aws_secret_access_key=getConfig('aws_secret_access_key',
'',
self.configfile)
self.options.aws_queue_name=getConfig('aws_queue_name',
'',
self.configfile)
def sendToCustomsServer(self,
ipaddress=None):
try:
if ipaddress is not None and self.options is not None:
# connect and send a message like:
# '{"Message": {"ban": {"ip": "192.168.0.2"}}}'
# encoded like this:
# {"Message":"{\"ban\":{\"ip\":\"192.168.0.2\"}}"}
conn = boto.sqs.connect_to_region(self.options.region,
aws_access_key_id=self.options.aws_access_key_id,
aws_secret_access_key=self.options.aws_secret_access_key)
queue = conn.get_queue(self.options.aws_queue_name)
banMessage = dict(Message=json.dumps(dict(ban=dict(ip=ipaddress))))
m = RawMessage()
m.set_body(json.dumps(banMessage))
queue.write(m)
sys.stdout.write('Sent {0} to customs server\n'.format(ipaddress))
except Exception as e:
sys.stderr.write('Error while sending to customs server %s: %r\n' % (ipaddress, e))
def onMessage(self, request, response):
'''
request: http://bottlepy.org/docs/dev/api.html#the-request-object
response: http://bottlepy.org/docs/dev/api.html#the-response-object
'''
# format/validate request.json:
ipaddress = None
CIDR = None
comment = None
duration = None
referenceID = None
userid = None
sendToCustomsServer = False
# loop through the fields of the form
# and fill in our values
try:
for i in request.json:
# were we checked?
if self.name in i.keys():
sendToCustomsServer = i.values()[0]
if 'ipaddress' in i.keys():
ipaddress = i.values()[0]
if 'duration' in i.keys():
duration = i.values()[0]
if 'comment' in i.keys():
comment = i.values()[0]
if 'referenceID' in i.keys():
referenceID = i.values()[0]
if 'userid' in i.keys():
userid = i.values()[0]
# are we configured?
if self.options is None:
sys.stderr.write("Customs server blockip requested but not configured\n")
sendToCustomsServer = False
if sendToCustomsServer and ipaddress is not None:
#figure out the CIDR mask
if isIPv4(ipaddress) or isIPv6(ipaddress):
ipcidr=netaddr.IPNetwork(ipaddress)
if not ipcidr.ip.is_loopback() \
and not ipcidr.ip.is_private() \
and not ipcidr.ip.is_reserved():
#split the ip vs cidr mask
ipaddress, CIDR = str(ipcidr.cidr).split('/')
self.sendToCustomsServer(ipaddress)
sys.stdout.write ('Sent {0}/{1} to customs server\n'.format(ipaddress, CIDR))
except Exception as e:
sys.stderr.write('Error handling request.json %r \n'% (e))
return (request, response)