Database Models & Connector
This commit is contained in:
		
							parent
							
								
									7d0749e562
								
							
						
					
					
						commit
						8ff4aaebbe
					
				
							
								
								
									
										35
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										35
									
								
								README.md
									
									
									
									
									
								
							@ -1,9 +1,42 @@
 | 
				
			|||||||
# Overseer
 | 
					# Overseer
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Description
 | 
					## Description
 | 
				
			||||||
Overseer is a port scanning web interface. All current and historical results are stored in a database.
 | 
					Overseer is a port scanning web interface. All current and historical results are stored in a database.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Building
 | 
					## Developing
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Server
 | 
				
			||||||
 | 
					Ideally from a virtualenv:
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					python setup.py develop
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Client
 | 
				
			||||||
 | 
					At this point, you have to build the client to appropriately populate the static resources for
 | 
				
			||||||
 | 
					the Flask server to serve up.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Building
 | 
				
			||||||
 | 
					Overseer consists of a server and client component.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Server:
 | 
				
			||||||
 | 
					Ideally from a virtualenv:
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					python setup.py install
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Client:
 | 
				
			||||||
 | 
					You must run these commands from the `./src/overseer_client/` directory:
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					yarn build
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Running
 | 
					## Running
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Ideally from a virtual env:
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					overseer run
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Notes
 | 
				
			||||||
 | 
					In a production environment, it would be ideal to setup something like nginx to properly forward
 | 
				
			||||||
 | 
					the `/api/*` routes to the Flask server, and all other endpoints to the static client resources.
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										3
									
								
								setup.py
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								setup.py
									
									
									
									
									
								
							@ -16,6 +16,7 @@ setup(
 | 
				
			|||||||
    },
 | 
					    },
 | 
				
			||||||
    install_requires = [
 | 
					    install_requires = [
 | 
				
			||||||
        "Flask",
 | 
					        "Flask",
 | 
				
			||||||
        "flask_socketio"
 | 
					        "flask_socketio",
 | 
				
			||||||
 | 
					        "sqlalchemy",
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
				
			|||||||
@ -0,0 +1,54 @@
 | 
				
			|||||||
 | 
					import models
 | 
				
			||||||
 | 
					from datetime import datetime
 | 
				
			||||||
 | 
					from os import path
 | 
				
			||||||
 | 
					from sqlalchemy import create_engine, or_, insert, Table, Column, Integer, String, ForeignKey, DateTime
 | 
				
			||||||
 | 
					from sqlalchemy.orm import declarative_base, Session
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class DatabaseConnector:
 | 
				
			||||||
 | 
					    def __init__(self, data_path):
 | 
				
			||||||
 | 
					        self.engine = create_engine("sqlite+pysqlite:///%s" % path.join(data_path, "overseer.sqlite"), echo=True, future=True)
 | 
				
			||||||
 | 
					        models.Base.metadata.create_all(self.engine)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def create_scan_result(self, ip_address, scan_results, hostname=None):
 | 
				
			||||||
 | 
					        session = Session(bind=self.engine)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Does an existing target exist?
 | 
				
			||||||
 | 
					        scan_target = session.query(models.ScanTarget).filter(or_(
 | 
				
			||||||
 | 
					            models.ScanTarget.ip==ip_address,
 | 
				
			||||||
 | 
					            models.ScanTarget.hostname==hostname,
 | 
				
			||||||
 | 
					        )).first()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Nope, create one
 | 
				
			||||||
 | 
					        if not scan_target:
 | 
				
			||||||
 | 
					            scan_target = models.ScanTarget(ip=ip_address, hostname=hostname)
 | 
				
			||||||
 | 
					            session.add(scan_target)
 | 
				
			||||||
 | 
					            session.commit()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Create scan history
 | 
				
			||||||
 | 
					        scan_history = models.ScanHistory(target=scan_target.id, results=",".join(map(str, scan_results)), datetime=datetime.now())
 | 
				
			||||||
 | 
					        session.add(scan_history)
 | 
				
			||||||
 | 
					        session.commit()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        session.close()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def create_target(self, ip_address, hostname):
 | 
				
			||||||
 | 
					        stmt = insert(models.ScanTarget).values(ip=ip_address, hostname=hostname)
 | 
				
			||||||
 | 
					        compiled = stmt.compile()
 | 
				
			||||||
 | 
					        self.__execute_statement(stmt)
 | 
				
			||||||
 | 
					        return stmt
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __execute_statement(self, stmt):
 | 
				
			||||||
 | 
					        with self.engine.connect() as conn:
 | 
				
			||||||
 | 
					            result = conn.execute(stmt)
 | 
				
			||||||
 | 
					            conn.commit()
 | 
				
			||||||
 | 
					            return result
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# FOR TESTING PURPOSES
 | 
				
			||||||
 | 
					def main():
 | 
				
			||||||
 | 
					    db = DatabaseConnector("/Users/evanreichard/Development/git/overseer/src/overseer")
 | 
				
			||||||
 | 
					    db.create_scan_result(1234577, [5,6,7,8], "test222.com")
 | 
				
			||||||
 | 
					if __name__ == "__main__":
 | 
				
			||||||
 | 
					    main()
 | 
				
			||||||
							
								
								
									
										37
									
								
								src/overseer/models.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								src/overseer/models.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,37 @@
 | 
				
			|||||||
 | 
					from sqlalchemy import Column, Integer, String, ForeignKey, DateTime
 | 
				
			||||||
 | 
					from sqlalchemy.orm import declarative_base
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Base = declarative_base()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ScanTarget(Base):
 | 
				
			||||||
 | 
					    __tablename__ = "scan_target"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Unique ID
 | 
				
			||||||
 | 
					    id = Column(Integer, primary_key=True, unique=True)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Integer representation of an IP Address. Can use SQL queries to filter subnets.
 | 
				
			||||||
 | 
					    ip = Column(Integer, index=True, unique=True)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Corresponding hostname.
 | 
				
			||||||
 | 
					    hostname = Column(String, index=True, unique=True)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __repr__(self):
 | 
				
			||||||
 | 
					        return f"ScanTarget(id={self.id!r}, ip={self.ip!r}, hostname={self.hostname!r})"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ScanHistory(Base):
 | 
				
			||||||
 | 
					    __tablename__ = "scan_history"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Unique ID
 | 
				
			||||||
 | 
					    id = Column(Integer, primary_key=True, unique=True)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Scan Target Reference
 | 
				
			||||||
 | 
					    target = Column(Integer, ForeignKey("scan_target.id"))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Results
 | 
				
			||||||
 | 
					    results = Column(String)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # DateTime
 | 
				
			||||||
 | 
					    datetime = Column(DateTime())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __repr__(self):
 | 
				
			||||||
 | 
					        return f"ScanHistory(id={self.id!r}, target={self.target!r}, results={self.results!r}, datetime={self.datetime!r})"
 | 
				
			||||||
							
								
								
									
										0
									
								
								src/overseer/scanner.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								src/overseer/scanner.py
									
									
									
									
									
										Normal file
									
								
							@ -11,6 +11,8 @@ yarn serve
 | 
				
			|||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
### Compiles and minifies for production
 | 
					### Compiles and minifies for production
 | 
				
			||||||
 | 
					This will automatically populate the overseer server with the appropriate resources in `templates` and `static`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
yarn build
 | 
					yarn build
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user