Files
heig-rapport-tb/chapitres/model/methodes.tex
2018-09-21 17:33:52 +02:00

119 lines
5.1 KiB
TeX

\section{Méthodes}
\subsection{route}
La méthode "route" retourne la route (\Colorbox{light-gray}{\lstinline|Route|}), utilisée par l'équipement (\Colorbox{light-gray}{\lstinline|Device|}) pour atteindre le réseau spécifié. C'est une mise en application de ce qui est expliqué dans la section \ref{subsec:network:ip:routing}. Pour y arriver, il faut donc obtenir celles dont les adresses limites du réseau comprennent celle du réseau voulu.
\vspace{3mm}
\begin{lstlisting}[language=Ruby, title="app/model/routing\_table.rb"]
# Params:
# * network: an IPv4 network to test
def route(network)
ip_net = IPAddr.new network
ip = ip_net.to_i
candidate_routes = routes.where(:start_ip.lte => ip, :end_ip.gte => ip)
choosed_route(candidate_routes)
end
\end{lstlisting}
\vspace{3mm}
Une fois les routes possibles obtenues, il faut encore isoler celle qui est la plus précise. Pour cela, il suffit de calculer le nombre d'adresses disponibles dans le réseau et de choisir celle qui en a le moins.
\vspace{3mm}
\begin{lstlisting}[language=Ruby, title="app/model/routing\_table.rb"]
# Params:
# * candidate_routes: a list of Route
def choosed_route(candidate_routes)
network_length = 4_294_967_296
choose_route = nil
candidate_routes.each do |candidate|
network = IPAddr.new candidate.network
network_size = network.to_range.last.to_i - network.to_range.first.to_i
if network_size < network_length
network_length = network_size
choose_route = candidate
end
end
choose_route
end
\end{lstlisting}
\vspace{3mm}
\subsection{crossed?}
\label{sec:methodes:crossed}
La méthode "crossed?" est un élément essentiel pour l'analyse des règles de sécurité (\Colorbox{light-gray}{\lstinline|Policy|}). Elle permet de déterminer sur un équipement (\Colorbox{light-gray}{\lstinline|Device|}) est traversé par un flux définit par deux réseaux. Pour cela, il faut utiliser la méthode "route" de la table de routage (\Colorbox{light-gray}{\lstinline|RoutingTable|}) de l'équipement en question et comparer l'interface de sortie des deux routes obtenues. Si elles sont différentes, cela signifique que le flux traverse ce firewall.
\begin{lstlisting}[language=Ruby, title="app/model/device.rb"]
# Params:
# * network1: the *source* network
# * network2: the *destination* network
def crossed?(network1, network2)
return false unless routing_table
route1 = routing_table.route(network1)
route2 = routing_table.route(network2)
return false unless route1 && route2
route1.interface != route2.interface
end
\end{lstlisting}
\subsection{matched\_policies}
\label{sec:methodes:matched_policies}
Cette méthode permet de gérer la fonctionnalité principale de l'application, soit de rechercher une règle spécifique en précisant une réseau source et distination, un protocole et un numéro de port.
\begin{lstlisting}[language=Ruby, title="app/model/device.rb"]
# Params:
# * request: the PolicyRequest with all the required informations
def matched_policies(request)
policies = []
policies_found = find_policies(request)
if !policies_found.empty? && request.include_all
policies += policies_found
elsif !policies_found.empty?
policies << policies_found.first
else
policies << implicit_policy
end
policies
end
\end{lstlisting}
Le but ici est de faire la requête de recherche et de retourner toutes les règles de sécurité obtenues ou bien uniquement la première en fonction de ce qui a été demandé dans la requête. Si aucune règle de sécurité n'est trouvée, la méthode va retourner une règle qui correspond à une règle implicite de blocage (par défaut sur firewall, ce qui n'est pas explicitement autorisé est bloqué).
\begin{lstlisting}[language=Ruby, title="app/model/device.rb"]
# Params:
# * request: the PolicyRequest with all the required informations
def find_policies(request)
source = matched_addresses(request.source)
source += matched_address_groups(source)
destination = matched_addresses(request.destination)
destination += matched_address_groups(destination)
service = matched_services(request.protocol, request.port)
service += matched_service_groups(service)
source_interface = zone_name(
routing_table.route(request.source).interface
)
destination_interface = zone_name(
routing_table.route(request.destination).interface
)
policies.where(
source_interface: source_interface,
destination_interface: destination_interface
).any_in(
source: source,
destination: destination,
service: service
)
end
\end{lstlisting}
La requête sur la base de donnée qui permet d'obtenir les règles de sécurité voulues est définie dans la fonction ci-dessus. Pour cela, il faut commencer par isoler les adresses source et destination ainsi que les services. On cherche ici à comparer des tableaux de String entre eux et à savoir si au moins un des éléments de ce tableau se retrouvent dans l'autre tableau. La méthode utilisée pour cela est "any\_in"\cite{stackanyin} en lui précisant les paramètres.