title: Nginx redirect all traffic to index.php, but don't allow arbitrary file access
body: <p>I have a legacy PHP app (Zend Framework) that I'm moving from Apache to Nginx. Except for things like web files (JS, CSS, images, fonts, etc.), all traffic needs to go through the <code>index.php</code> file in the root of the project folder. So I need to redirect all traffic to <code>index.php</code>, except for web files.</p>
  <p>There are a lot of solutions to this that use <code>try_files</code> as a catch-all. Basically if a file is not found on the filesystem, nginx will send the request to <code>index.php</code>.</p>
  <p>The problem with this is that the app stores its configuration file in a web-accessible path (i.e. in a subdirectory of the folder that holds <code>index.php</code>). So you could point your browser to the configuration file path and read it (e.g. <code>https://example.com/config/app.xml</code>). Since the file exists on the filesystem, nginx will serve it. There are actually a few more project config files that can be accessed in this way too.</p>
  <p>So, how do I send all requests to <code>index.php</code>, except for web files, and also not allow arbitrary files to be read from the web?</p>
  <p>Yes, I know I could update the app to access the config files in another location, but it's legacy and not super crucial. I don't want to spend more time on it than I have to and I don't want to break it.</p>
  <p>I could also forbid access to any extensions that happen to be config files (e.g. <code>xml</code>, <code>yml</code>, etc.), but it's a big project and I don't want to risk missing something.</p>
  <p>I figured out a solution. I didn't find anything that worked exactly the way I wanted online, so I'm asking this question in order to answer it.</p>