mirror of
https://github.com/outbackdingo/sysadm.git
synced 2026-01-27 18:20:23 +00:00
Add IP blacklisting to the sysadm server.
Current Settings: 1) 5 auth attempts allowed before failover 2) If no communications for 10 minutes, the failover counter gets reset 3) On failover - the IP is placed on the server blacklist for 1 hour Note: The blacklist system is connection independant, and uses the host IP for unique tracking/blocking.
This commit is contained in:
@@ -15,6 +15,7 @@ WebServer::WebServer(){
|
||||
WSServer = 0;
|
||||
TCPServer = 0;
|
||||
AUTH = new AuthorizationManager();
|
||||
connect(AUTH, SIGNAL(BlockHost(QHostAddress)), this, SLOT(BlackListConnection(QHostAddress)) );
|
||||
}
|
||||
|
||||
WebServer::~WebServer(){
|
||||
@@ -97,6 +98,24 @@ bool WebServer::setupTcp(quint16 port){
|
||||
return TCPServer->listen(QHostAddress::Any, port);
|
||||
}
|
||||
|
||||
//Server Blacklist / DDOS mitigator
|
||||
bool WebServer::allowConnection(QHostAddress addr){
|
||||
//Check if this addr is on the blacklist
|
||||
QString key = "blacklist/"+addr.toString();
|
||||
if(!CONFIG->contains(key) ){ return true; } //not in the list
|
||||
//Address on the list - see if the timeout has expired
|
||||
QDateTime dt = CONFIG->value(key,QDateTime()).toDateTime();
|
||||
int minblock = CONFIG->value("blacklist/RefuseMinutes",60).toInt();
|
||||
if(dt.addSecs(minblock*60) < QDateTime::currentDateTime()){
|
||||
//This entry has timed out - go ahead and allow it
|
||||
CONFIG->remove(key); //make the next connection check for this IP faster again
|
||||
return true;
|
||||
}else{
|
||||
return false; //blacklist block is still in effect
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
QString WebServer::generateID(){
|
||||
int id = 0;
|
||||
for(int i=0; i<OpenSockets.length(); i++){
|
||||
@@ -113,14 +132,23 @@ QString WebServer::generateID(){
|
||||
void WebServer::NewSocketConnection(){
|
||||
WebSocket *sock = 0;
|
||||
if(WSServer!=0){
|
||||
if(WSServer->hasPendingConnections()){ sock = new WebSocket( WSServer->nextPendingConnection(), generateID(), AUTH); }
|
||||
if(WSServer->hasPendingConnections()){
|
||||
QWebSocket *ws = WSServer->nextPendingConnection();
|
||||
if( !allowConnection(ws->peerAddress()) ){ ws->close(); }
|
||||
else{ sock = new WebSocket( ws, generateID(), AUTH); }
|
||||
}
|
||||
}else if(TCPServer!=0){
|
||||
if(TCPServer->hasPendingConnections()){ sock = new WebSocket( TCPServer->nextPendingConnection(), generateID(), AUTH); }
|
||||
if(TCPServer->hasPendingConnections()){
|
||||
QSslSocket *ss = TCPServer->nextPendingConnection();
|
||||
if( !allowConnection(ss->peerAddress()) ){ ss->close(); }
|
||||
else{ sock = new WebSocket( ss, generateID(), AUTH); }
|
||||
}
|
||||
}
|
||||
if(sock==0){ return; } //no new connection
|
||||
qDebug() << "New Socket Connection";
|
||||
connect(sock, SIGNAL(SocketClosed(QString)), this, SLOT(SocketClosed(QString)) );
|
||||
connect(EVENTS, SIGNAL(NewEvent(EventWatcher::EVENT_TYPE, QJsonValue)), sock, SLOT(EventUpdate(EventWatcher::EVENT_TYPE, QJsonValue)) );
|
||||
connect(sock, SIGNAL(BlackListAddress(QHostAddress)), this, SLOT(BlackListConnection(QHostAddress)) );
|
||||
OpenSockets << sock;
|
||||
}
|
||||
|
||||
@@ -129,6 +157,15 @@ void WebServer::NewConnectError(QAbstractSocket::SocketError err){
|
||||
QTimer::singleShot(0,this, SLOT(NewSocketConnection()) ); //check for a new connection
|
||||
}
|
||||
|
||||
//Socket Blacklist function
|
||||
void WebServer::BlackListConnection(QHostAddress addr){
|
||||
//Make sure this is not the localhost (never block that)
|
||||
if(addr!= QHostAddress(QHostAddress::LocalHost) && addr != QHostAddress(QHostAddress::LocalHostIPv6) ){
|
||||
//Block this remote host
|
||||
CONFIG->setValue("blacklist/"+addr.toString(), QDateTime::currentDateTime());
|
||||
}
|
||||
}
|
||||
|
||||
//WEBSOCKET SERVER SIGNALS
|
||||
// Overall Server signals
|
||||
void WebServer::ServerClosed(){
|
||||
|
||||
Reference in New Issue
Block a user