Você está na página 1de 12

Building

a Raspberry Pi Captive Portal


WiFi Hotspot
byian@cybersecurityguy.com

Introduction
IhaveaRaspberryPithathasbeenlyingaroundforawhile,andIdecidedIwouldfinallydoafun
projectwithitthatIcouldsharewithmykidstointroducethemtoawiderangeofskills,includingLinux,
wirelesstechnologiesaswellasthesocialaspectofhumanbehaviorwithtechnology.Thisprojectwill
takeaRaspberryPiandturnitintowhatiscommonlyreferredtoasacaptiveportalWiFihotspot.But
first,letsexplainwhatthatreallymeans.

Asmostofusalreadyknow,aWiFihotspotisanopenwirelessnetworkthatyoucanusetoconnectto
theInternet.Sometimesthesearefree,andothertimestheyrequireaformofpayment.Withanormal
WiFinetwork,youjustconnect,enteryourpassword,andyoureontheInternet.Acaptiveportalis
onethatblocksyoufromgoingstraighttotheInternet,andinsteadcapturesallofyourwebtrafficand
redirectsyoutoawebpage,whereyoucanagreetotheirtermsandconditions,andsometimeslogin
and/orprovidepayment.Onceyouveperformedwhateveractionisrequiredattheportalpage,you
canthenaccesstheInternetforsomelengthoftime.

Inthisproject,wewillbebuildingaRaspberryPitoactuallydoseveralofthesefunctions.First,wewill
buildittobearegularWiFihotspot,andIllshowyouwhereyoucoulduseitasyourownpersonal
accesspoint.ThenIllshowyouhowyoucanfurthermodifyittobeacaptiveportalwithasinglepage
thatprovidesalistoftermsandconditionsandanacceptbutton.ThenIllshowyouhowyoucan
modifyitfurthertobeafakeWiFipublichotspotwithacaptiveportalthatactuallydoesntconnectto
theInternetatall.AndIllexplainwhyyoumightbeinterestedindoingthat,forasocialexperiment.

Project Requirements
Beforewebegin,letscoverexactlywhatwellbeusingforthisproject.Ifyoudontusetheseexact
parts,youllprobablybefine,butyouwillneedtomakeadjustmentsandfindsomeofyourown
solutionsalongtheway.YoumightwanttousethesamewirelesscardIspecifybelow,becausenotall
cardscanactasAccessPointwiththeappropriatesoftware.Soifyouarefollowingalongandlookingto
buypartsforthissolution,Iwouldstronglyencourageyoutogetthisspecificcardtominimizepainand
frustration.

RaspberryPi(anymodelwillsuffice)
EDIMaxMiniUSBWirelessadapter(modelEW7811UN)
USBkeyboard
HDMIcableforyourmodelofRaspberryPi
MonitorwithHDMIinput

1
Preparing the Operating System
Youmightthinkthatthefirstthingweneedtodoistoconnectallthehardwaretogether,butitsnot.
ThefirstthingweneedtodoistogetanoperatingsysteminstalledontotheSDmemorycard.Thisis
because,withoutsoftware,thereisntanythingwecandowiththehardware.RightnowwehaveanSD
memorycardwithnothingonit.Wewillneedtodownloadtheoperatingsystemontothismemorycard
sothattheRaspberryPicanloaditandfunction.

ThereareseveraldifferentoperatingsystemsthatwecanloadontotheRaspberryPi.Theyareallbased
uponavariantoftheLinuxoperatingsystem,whereasyoumaybenormallyusedtousingtheWindows
orMacoperatingsystems.TheonethatwewilluseinthisprojectiscalledRaspbian.Ratherthanre
writewhatarealreadygreatinstructions,Illjustrefertothembelow.Followtheinstructionsatthelink
providedbelowtodownloadNOOBSandinstalltheRaspbianoperatingsystem.Aspartofthis,youwill
installthesoftwareyouneedtowritetheoperatingsystemtotheSDmemorycard,andinstallitonto
thecard.Onceyouvedoneallofthis,andyouhavesuccessfullywrittentheRaspbianoperatingsystem
ontotheSDmemorycard,proceedwiththerestofmyinstructionsinthenextsection.

https://www.raspberrypi.org/documentation/installation/installingimages/README.md

Preparing the Hardware


Prepareyourhardwareasfollows:

1. InserttheSDmemorycardwithRaspbianinstalledintothePi.
2. ConnectthenetworkcabletothePi.MakesureitwillbeabletoconnecttotheInternetdirectly
withoutanyspecialconfiguration.Technicallyspeaking,thenetworkwillneedtoprovideDHCP
totheRaspberryPi.Ifyoudontknowwhatthismeans,dontworry,youllalmostcertainlybe
finehere.
3. ConnecttheWiFiUSBadaptertothePi.
4. ConnectaUSBkeyboardtothePi.
5. ConnectanHDMIcabletoyourmonitorandthePi.Makesureyouswitchyourmonitoronand
tothecorrectinput.
6. ConnectthepowertothePi.

Youshouldseeabootupsequenceorsomeformofactivity.AsRaspbianmayhavechangedabitsince
thisguidewaswritten,justfollowwhateverquestionsorpromptsyouaregivenuntilyougettothe
pointwhereyouareprovidedwithaloginprompt.Thatswherewewillbeginthenextsection.

2
Configuring the Pi as a WiFi Hotspot
Thisis,byfar,wheremostofthemeatandcomplexitylies.Wevealreadytakencareofourhardware,
sostrapinandgetreadyfortheride.IfyourenotalreadyfamiliarwithLinux,youregoingtobe
confusedwithwhatisgoingonhere.ThatsOK.Illexplainsomeofwhatishappeningalongtheway,
justenoughsothatyouhavesomebasicinformationaboutwhatishappening.IfIdomyjobherewell
enough,hopefullyitwillgetyouinterested,perhapsevenexcited,tolearnmorethanwhatiscovered
beyondthisguide.

Letsbegin!

1. Youwillfirstneedtologin,ifyouhaventalreadyloggedinalready.ThedefaultloginofRaspbianis
ausernameofpiandapasswordofraspberry.Sogoaheadandtypeintheusername,press
enter,followedbythepasswordandenter.Youshouldgetapromptbackthatlookssomewhatlike
thefollowing:

loginas:pi

2. Nowthatwehaveaccesstothesystem,letschangethepassword.Wedothatwiththepasswd
command.Typethat,pressenter,anditwillaskyouforyourcurrentpasswordandtoenterand
confirmyournewpassword.Dontforgetyournewpassword,oryouwillneedtoreinstallRaspbian
ontoyourSDmemorycardagainandstartfromthebeginning!

pi@raspberrypi~$passwd

3. Beforewegoanyfurther,letsconfirmthatwehaveaworkingInternetconnection.Letsping
Googletomakesurewehaveproperconnectivity.ThiswillverifythatwehavebeenassignedanIP
address,thatweareabletoresolveDNShostnames(suchaswww.google.com,whichconvertsit
intoanIPaddress),andthatourtrafficisflowingallthewayouttoGooglesservers,andthattheir
serversarerespondingallthewaybacktous.Itsagreatwaytoconfirmthateverythingisworking
inasinglestep.

pi@raspberrypi~$pingwww.google.com

PINGwww.google.com(74.125.227.24)56(84)bytesofdata.

64bytesfromdfw06s38inf17.1e100.net(74.125.227.24):icmp_req=1ttl=57time=12ms

4. Ifeverythingisworking,youllgetaresponsethatshowsicmp_req=likethatshownabove,andit
willcontinuetorepeatoverandover.ThatsbecausethePINGcommandwillkeepsendingrequests
untilyouinterruptit.YoullneedtointerruptitbypressingCTRLConyourkeyboard,afterwhich
youllseeasummaryoftheresponse,followedbythesystemprompt.

Ifforsomereasonthisdoesntwork,checktomakesureyournetworkcableispluggedin.Ifyouhad
acablingproblem,youllwanttoresetthepoweronyourPiandtryagain.Ifyoustillhavetrouble,
youllprobablyneedtocontactsomeonewhounderstandsnetworking,ortryanotherconnection.

3

Asasidenote,thenumbersshownontheicmp_req=lineisprettyinteresting.Theoneshown
aboveshows12.9ms.Thatmeansthatittook12.9millisecondstosendanetworkpacketto
Googlesservers,fortheirservertoprocessit,andforittogetallthewaybacktothePi.Wecallthis
theroundtriptime.Thatsprettyamazing!

5. Next,makesureallofthesoftwarewehaveinstalledisuptodatewithallrecentpatches.Wedo
thisbyusingtheAdvancedPackagingTool,whichisusedtomanagesoftwarepackagesinstalled
onthesystem.Thecommandlineforthisisaptgetupdate.Thiscommandisverypowerfulandas
suchrequiresadministrative,otherwiseknownasrootorsuperuserprivilegesintheLinux
world.Wecanrunthis,andotherpowerfulcommands,byprecedingthecommandwithsudo
(shortforsuperuserdo<something>).Keepthisinmind!Throughoutthisguidewearegoingto
usethesudocommandalot.Ifyouforgettotypeit,whichyouprobablywillatsomepoint,youll
likelygetsomeveryweirderrormessage.Ifyouevergetaweirderrormessageyouwerent
expecting,itsagoodideatodoublecheckthatyouranthecommandassuperuser(ifitis
necessary).

pi@raspberrypi~$sudoaptgetupdate

Whenyourunthecommandbelow,itwillaskyoutoconfirmthatyouwanttodownloadandinstall
alltheupdatedsoftware.YouwillneedtoanswerthatwithaYinresponse.

6. Alright,nowwearereadytostartinstallingsomeothersoftware.Nextupisapackagecalled
hostapd.ThisisusedtomakeaLinuxsystemactasanWiFiAccessPoint,orAPforshort.That
meansthat,insteadofthePibeingabletojoinintoaWiFinetwork,otherWiFideviceswillbeable
toseethePiandbeabletoconnectintoit.Wewillusetheaptgettoolagain,butthistimewere
goingtotellittoinstallthehostAPpackage.

pi@raspberrypi~$sudoaptgetinstallhostapd

Asanotheraside,asyoustartinstallingmoresoftwareinLinux,youmaynoticealotofpackages
endind,likehostapdhere.Thedisshortfordaemon,whichbasicallymeansthatitisa
servicethatrunsinthebackgroundofthesystem,insteadof,forexample,anapplicationthat
displaysoutputonthescreenandrequiresuserinputfromthekeyboard.Adaemonjustruns
withoutneedinganyofthat.

7. Wehavethehostapdaemoninstallednow,butthereisabuginitthatweneedtofix.Illspareyou
thegorydetails,butsufficeittosaythatweneedtoreplaceaparticularfiletogetittowork
correctlywithourwirelessadapter.Justgowithmeonthis.First,letsdownloadthefileweneed.
Wedownloadthefileusingthewgettool,wherethewstandsforweb.

pi@raspberrypi~$wgethttp://dl.dropbox.com/u/1663660/hostapd/hostapd.zip

8. Nowthatwehavethisfile,weneedtounzipit,becauseitiscompressed.

4
pi@raspberrypi~$unziphostapd.zip

9. Nowweneedtocopy(cp)thisfileovertheoriginalone.

pi@raspberrypi~$sudocphostapd/usr/sbin/hostapd

10. Nowthatthehostapdaemonisinstalled,weneedtoconfigureitforourenvironment.Wewilluse
thenanotexteditorinordertodothis.Itisnotlikethetexteditorsyouareusedto.Itlooksand
feelsmorecomplex.So,letstakethisonestepatatime.First,letslaunchnanotoeditthefile.

pi@raspberrypi~$sudonano/etc/hostapd/hostapd.conf

Type(orcopyandpaste)thefollowinglinesintothefile.

interface=wlan0
driver=rtl871xdrv
ssid=FREEPUBLICWIFI
hw_mode=g
channel=11
macaddr_acl=0

SavethefilebypressingCTRLO.ItshouldaskyoufortheFileNametoWrite.Youcanacceptthe
defaultbyjustpressingenter.Onceyoudo,itshouldsay[Wrote<#>lines]nearthebottomcenter
ofthescreen.ExitfromnanobypressingCTRLX.KeeptheseeditingCTRLcommandsinmind,as
wellbeusingthemafewmoretimes.

11. Letstestwhatwehavedonesofar.Letsstartuphostapandseewhathappens!

pi@raspberrypi~$sudohostapd/etc/hostapd/hostapd.conf

NowcheckwithanotherwirelessdeviceandseeifyoucanfindaWiFinetworkwiththenameof
FREEPUBLICWIFI.Ifyoucan,awesome,wereallgoodsofar.Dontbothertryingtoconnecttoit
yet,though.Itwontworkproperly,becausearearentdone.PressCTRLCtoexitfromthehostap
daemon.Ifitdidntwork,oryougotanyerrorsalongtheway,recheckyourworkbetweensteps5
andhere.

12. Aswehavenowconfirmedthatwehavehostapdworking,letssetituptoalwaysrunwhenthePi
startsup.

pi@raspberrypi~$sudonano/etc/rc.local

Atthebottomofthisfile,butabovethelinethatsaysexit0.

hostapdB/etc/hostapd/hostapd.conf

5
Saveandexitthefile.Whenoursystemrebootsthenexttime,itwillautomaticallyrunhostapdin
thebackgroundusingtheconfigurationfilewecustomized.

13. NowwewillinstallaDHCPserver.DHCPisshortforDynamicHostConfigurationProtocol.In
simplerterms,itsthedaemonthatwillprovideanIPaddress,DNSserverIPaddress(welltalk
aboutthatlater)andotherconfigurationinformationtoourwirelessclientsthatconnecttoourAP.
WithoutthisinformationthewirelessclientswouldntbeabletocommunicatewiththePi(or
anythingelse)usingthelanguageoftheInternet(technicallyreferredtoasanetworkprotocol).

pi@raspberrypi~$sudoaptgetinstalliscdhcpserver

14. WeneedtoedittheconfigurationoftheDHCPserver.Wewillusenanoagaintodothis.

pi@raspberrypi~$sudonano/etc/dhcp/dhcpd.conf

Findthelinethatstartswith#authoritativeandremovethe#infrontofit.Thengodowntothe
endofthefile,andcopyandpastethefollowingtext.

subnet10.0.10.0netmask255.255.255.0{
range10.0.10.210.0.10.254
optiondomainname"schoolscienceproject.com";
optiondomainnameservers8.8.8.8,8.8.4.4;
optionrouters10.0.10.1;
interfacewlan0;
}

Savethefileandexitwhenyouaredone.Youcanchangeyourdomainnameheretowhateveryou
like,justbeniceanddontusesomethingthatalreadyexists.

15. NowweneedtoassigntheproperIPaddresstoourwirelessAPinterface.Wejustfinished
configuringthewirelessclienttoreceiveadynamicIPaddressfromthePi,butweneedtohavea
fixed(static)IPaddressthatdoesntchangeforthePi.Itskindoflikehavingafixedbusiness
address,soourcustomersknowwherewearealwayslocated.

pi@raspberrypi~$sudonano/etc/network/interfaces

Locatetheplaceinthefilewhereitsaysifacewlan0inetmanual.Changethemanualtoread
static,andaddthefollowinglinesimmediatelybelowit.

address10.0.10.1
netmask255.255.255.0

Saveandexitthefilewhenyouaredone.

6
16. Weneedtoenablesomethingcalledipforwarding.Thisallowsthewirelessclientstotransferdata
notjusttothePi,butthroughit.Enablingthisiswhatallowstraffictocomeinoneinterface(theWi
Fi)andgooutanother(thenetworkcable),andviceversa.Weneedthisinordertogetthewireless
clientdatatogothroughthePiandouttotheInternetandback.

pi@raspberrypi~$sudonano/etc/sysctl.conf

Locatethelineinthefilewhereitsays#net.ipv4.ip_forward=1,andremovingtheleading#.
Savethefileandexit.

17. Nowhereisabitofadvancedtrickerythatismoredifficulttowraponesheadaround.Itenables
somethingcalledNetworkAddressTranslation,orNAT.ThisisatopicbetterleftforalaterGoogle
search.Fornow,justtypethiscommand.

pi@raspberrypi~$sudoiptablestnatAPOSTROUTINGoeth0jMASQUERADE

18. Weneedtomakesurethatthechangewejustmakeissaved,orpersists,betweenreboots.We
needtoinstallanothersoftwarepackageinorderforthistohappen.Duringinstallation,youwillbe
askedifyouwanttosavethecurrentrules.Sayyes.

pi@raspberrypi~$sudoaptgetinstalliptablespersistent

19. Atthispoint,wehaveinstalledandconfiguredallofthesoftwareweneedinordertohavethePi
functionasaWiFiHotspot.Allweneedtodonowisrebootitinordertogeteverythingtoload.We
willusetheshutdowncommand,andtellittoreboot(r),andtodoitimmediately(now).

pi@raspberrypi~$sudoshutdownrnow

20. WaitforthePitoreboot,andgiveitafewextraminutesforeverythingtoloadproperly.Thentry
connectingwithaWiFideviceandbrowseouttotheInternet.Ifitworks,congratulations!Ifit
doesnt,gobackandcheckthestepsabove.

WARNING!

ThisconfigurationwassimplifiedtohavetheAPbewithoutanyencryption.Asitiscurrentlyconfigured,
anyonewillbeabletoconnecttoyournetworkandnotonlybrowsetheInternet,butbrowseyour
internalnetwork.IfyouwanttokeepusingtheAPasapersonalWiFihotspot,thenyoullwantto
configureapasswordforthenetworkandenablestrongsecurity.Youcanfindmoreinformationabout
configuringthisinthehostapd.conffileyoueditedearlier,aswellasotheronlineresources.

7
Configuring the Pi as a Captive Portal
NowthatyouhaveyourPiworkingasahotspot,letsgofurtherandmakeitacaptiveportal.Thismeans
thatwhensomeoneconnects,itwillpresentawebpagethattheymustclickabuttonontocontinue.
TheywillnotbeabletoaccessanyInternetsiteuntiltheyclickthebutton.Thispagewouldnormally
includealistoftermsandconditionsforaccessingthehotspot,andthebuttonwouldtypicallysay
somethinglikeIaccept.

21. LogbackinthePi,andletsinstallthenodogsplashcaptiveportalsoftware.Inthisseriesofsteps,
wewilldownloadthesoftware,uncompress,compileandinstallit.

pi@raspberrypi~$
wgethttps://github.com/nodogsplash/nodogsplash/archive/master.zip
pi@raspberrypi~$unzipmaster.zip
pi@raspberrypi~$rmmaster.zip
pi@raspberrypi~$cdnodogsplashmaster
pi@raspberrypi~$make
pi@raspberrypi~$sudomakeinstall

22. Weneedtoconfigurenodogsplashbyeditingtheconfigurationfile.

pi@raspberrypi~$sudonano/etc/nodogsplash/nodogsplash.conf

Pastethefollowinginformationintothefile,thensaveandexit.

GatewayInterfacewlan0
GatewayAddress10.0.10.1
MaxClients250
ClientIdleTimeout480

23. Nowsthefunpartwherewecaneditthewebpagetodisplaywhateverwewant.Bydefault,
nodogsplashincludesabasicpage.Makewhatevereditsyouwant,butmakesureyouretainthe
partinthefilewhereitletstheuserclicktojointhenetwork.

pi@raspberrypi ~ $ sudo nano /etc/nodogsplash/htdocs/splash.html

24. Onceyouveeditedyourwebpage,letsstartnodogsplash.

pi@raspberrypi~$sudonodogsplash

25. Connecttothehotspot,andseeifyoureceivethesplashpagewhenyoutrytobrowseoutto
http://www.google.comwithawirelessclient.

8
26. Nowthatweknowthatnodogsplashisworking,weneedtosetituptorunwhenthePistarts.Todo
that,weneedtoaddittothe/etc/rc.localfile.

pi@raspberrypi~$sudonano/etc/rc.local

Findthelineyouaddedearliertothisfile,andaddthefollowinglinebeneathit.

nodogsplash

27. Atthispoint,yourcaptiveportalisworkingandshouldcontinuetoworkwhenyoureboot!
Congratulations!

Ifyoudliketokeepalogofthedevicesthatconnecttoyourcaptiveportal,includingthosethat
clicktheacceptbutton,youcanoutputstatusonaregularbasistoalogfile.Wewilldothisby
addingentriestothecrontab,whichcontainsalistofcommandsthatthesystemwillrunona
recurringbasis.Toeditthisconfiguration,usethefollowingcommand.

pi@raspberrypi~$sudocrontabe

Addthefollowinglinestotheendofthefile.Thefirstlineinstructsthesystemto,every5minutes,
outputthestatusofnodogsplash(usingthendsctlutility)toafilenamed/root/results5.txt.A
singlegreaterthansymbolwouldmeanthatwewouldoverwritethisfileeverytimeitruns,butI
prefertoappendtothefilesothatwedontaccidentallyloseanydata,becausethenodogsplash
clientstatuswillreseteverytimethedevicereboots.Ialsoliketohaveabackup,soIalsohaveit
runningevery15minutesaswell,andoutputtingtoadifferentfilename.

*/5****ndsctlstatus>>/root/results5.txt
*/15****ndsctlstatus>>/root/results15.txt

9
Configuring the Pi as a Fake Captive Portal
IfyoudonthaveanInternetconnection,butyoustillwantyourPitoactasaWiFicaptiveportal,you
candosomemoreconfigurationtoaddtheservicesyouneedtofakeanInternetconnection.

28. OneoftheservicesthatisrequiredforInternetaccessisDNS,whichstandsforDomainName
System.EverythingontheInternettalksusingIPaddresses.Whenyoutrytoaccess
www.google.com,forexample,yourcomputerfirstperformsaDNSlookuponthistogetbackanIP
address.OnlyonceithasanIPaddressdoesyourcomputerthenmakeaconnectiontotheserver,
usingthatIPaddress.WearegoingtosetupaDNSserveronthePiwhichrespondstoeveryrequest
withtheIPaddressofthePiitself.Soregardlessofwherethewirelessclientistryingtoconnect,it
willalwaysdirectthembacktotheIPaddressofthePi.Wewillinstallbind,aDNSserver.

pi@raspberrypi~$sudoaptgetinstallbind9

29. NextweneedtoconfiguretheDNSserver.

pi@raspberrypi~$sudonano/etc/bind/named.conf.local

30. Addallofthisattheendofthefile.

zone"."{
typemaster;
file"/etc/bind/db.catchall";
};

31. Wealsoneedtomodifyanoptionsfile.

pi@raspberrypi~$sudonano/etc/bind/named.conf.options

32. Findthelinethatsaysdir=/etc/namedbandchangeittothefollowing.

dir=/etc/bind

33. Andweneedtocreatethisfile.

pi@raspberrypi~$sudonano/etc/bind/db.catchall

10
34. Addallofthisinfothefile.

$TTL604800
@INSOA.root.localhost.(
1;Serial
604800;Refresh
86400;Retry
2419200;Expire
604800);NegativeCacheTTL

IN NS .
. IN A 10.0.10.1
*. IN A 10.0.10.1

35. WeneedtomakesuretheDNSserverstartsonboot,soagainweneedtoeditthe/etc/rc.local
file.

pi@raspberrypi~$sudonano/etc/rc.local

36. Findthelineyouaddedearliertothisfile,andaddthefollowinglinebeneathit.

namedubind

37. NowweneedtoreconfigureourDHCPserversothatwhenthewirelessclientsconnect,theyare
toldtousethePiastheirDNSserver.

pi@raspberrypi~$sudonano/etc/dhcp/dhcp.conf

38. Findthelineinthefilethatsaysandchangeittoreadthefollowing.RecallthattheIPaddresswe
usedforthePiis10.0.10.1.

optiondomainnameservers10.0.10.1;

39. NowdisconnectthenetworkcableonthePiandreboot.Tryconnectingwithawirelessclient,and
seeifyoustillgetthecaptiveportalsplashpage.Ifyoudo,congratulations,youredone!

11
In Closing
Hopefullythisguidehashelpedyoutocompletethisprojectsuccessfully.Ihopethatyouvelearned
somethingnewalongtheway,andhavehadfundoingso.Ifyouhaveanyquestionsorcomments,
pleasefeelfreetodropmeabitatian@cybersecurity.com.

About Me
ImanInformationSecurityandInformationTechnologyprofessionalwholivesintheAustin,Texasarea.
Imawhitehatwhopreferstocreateratherthandestroyandusemypowersforgoodandnotevil.Ive
attackedanddefendedcompanieslargeandsmall,withnotablesincludingHomeDepot,theStateof
Texas,Amazon,andIBM.Iveprovidedresponsibledisclosureformultiplehighprofileexploits.Myarea
ofspecialtyisbroadandrangesfromnetwork,serverandapplicationsecurity,penetrationtesting,
reverseengineeringandalmosteverythinginbetween.Ivespokenonmultipletopicsatvarioussecurity
conferencesaroundthecountryincludingDerbyCon,BSidesAustin/Dallas/SanAntonio,HouSecConand
others.Impassionateaboutsecurityandtechnologyandlearningnewthings,especiallywherethetwo
intersect.

12

Você também pode gostar